Merge pull request #9 from AAPS-Omnipod/omnipod_eros_dev_properly_decode_pod_info_02
Properly decode Pod info response type 02 + pairing fixes for Activation Time Exceeded errors
This commit is contained in:
commit
f3ec652893
36 changed files with 774 additions and 567 deletions
|
@ -30,6 +30,7 @@ import info.nightscout.androidaps.plugins.profile.local.LocalProfileFragment
|
|||
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
|
||||
import info.nightscout.androidaps.plugins.profile.ns.NSProfileFragment
|
||||
import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin
|
||||
import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodPumpPlugin
|
||||
import info.nightscout.androidaps.setupwizard.elements.*
|
||||
import info.nightscout.androidaps.setupwizard.events.EventSWUpdate
|
||||
|
@ -324,6 +325,12 @@ class SWDefinition @Inject constructor(
|
|||
val activePump = activePlugin.activePump
|
||||
activePump is OmnipodPumpPlugin && !activePump.isRileyLinkReady
|
||||
}))
|
||||
.add( // Omnipod only
|
||||
SWEventListener(injector, EventRileyLinkDeviceStatusChange::class.java)
|
||||
.label(R.string.setupwizard_pump_riley_link_status)
|
||||
.visibility(SWValidator {
|
||||
activePlugin.activePump is OmnipodPumpPlugin
|
||||
}))
|
||||
.add(SWButton(injector)
|
||||
.text(R.string.readstatus)
|
||||
.action(Runnable { commandQueue.readStatus("Clicked connect to pump", null) })
|
||||
|
@ -332,7 +339,8 @@ class SWDefinition @Inject constructor(
|
|||
// Getting the status might not be possible
|
||||
activePlugin.activePump !is OmnipodPumpPlugin
|
||||
}))
|
||||
.add(SWEventListener(injector, EventPumpStatusChanged::class.java))
|
||||
.add(SWEventListener(injector, EventPumpStatusChanged::class.java)
|
||||
.visibility(SWValidator { activePlugin.activePump !is OmnipodPumpPlugin }))
|
||||
.validator(SWValidator {
|
||||
isPumpInitialized()
|
||||
})
|
||||
|
|
|
@ -11,7 +11,7 @@ import io.reactivex.android.schedulers.AndroidSchedulers
|
|||
import io.reactivex.disposables.CompositeDisposable
|
||||
|
||||
class SWEventListener constructor(
|
||||
injector:HasAndroidInjector,
|
||||
injector: HasAndroidInjector,
|
||||
clazz: Class<out EventStatus>
|
||||
) : SWItem(injector, Type.LISTENER) {
|
||||
|
||||
|
@ -19,6 +19,7 @@ class SWEventListener constructor(
|
|||
private var textLabel = 0
|
||||
private var status = ""
|
||||
private var textView: TextView? = null
|
||||
private var visibilityValidator: SWValidator? = null
|
||||
|
||||
// TODO: Adrian how to clear disposable in this case?
|
||||
init {
|
||||
|
@ -43,6 +44,11 @@ class SWEventListener constructor(
|
|||
return this
|
||||
}
|
||||
|
||||
fun visibility(visibilityValidator: SWValidator): SWEventListener {
|
||||
this.visibilityValidator = visibilityValidator
|
||||
return this
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun generateDialog(layout: LinearLayout) {
|
||||
val context = layout.context
|
||||
|
@ -51,4 +57,8 @@ class SWEventListener constructor(
|
|||
textView?.text = (if (textLabel != 0) resourceHelper.gs(textLabel) else "") + " " + status
|
||||
layout.addView(textView)
|
||||
}
|
||||
|
||||
override fun processVisibility() {
|
||||
if (visibilityValidator != null && !visibilityValidator!!.isValid) textView?.visibility = View.GONE else textView?.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
|
@ -1443,4 +1443,5 @@
|
|||
<string name="worker_state">Worker State: %s</string>
|
||||
<string name="uploaded_data">Uploaded Data</string>
|
||||
<string name="the_following_data_will_be_uploaded_to_your_open_humans_account">The following data will be uploaded to your Open Humans account: Glucose values, boluses, carbs, careportal events (except notes), extended boluses, profile switches, total daily doses, temporary basals, temp targets, preferences, application version, device model and screen dimensions. Secret or private information such as your Nightscout URL or API secret will not be uploaded.</string>
|
||||
<string name="setupwizard_pump_riley_link_status">RileyLink status:</string>
|
||||
</resources>
|
||||
|
|
|
@ -72,6 +72,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.definition.OmnipodCustomA
|
|||
import info.nightscout.androidaps.plugins.pump.omnipod.definition.OmnipodStorageKeys;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.service.ExpirationReminderBuilder;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoRecentPulseLog;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.ActivationProgress;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertConfiguration;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager;
|
||||
|
@ -254,6 +255,13 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
|
|||
// When PodStateManager is created, which causes an IllegalArgumentException for DateTimeZones not being recognized
|
||||
podStateManager.loadPodState();
|
||||
|
||||
// BS @ 2020-10-17 FIXME: for backwards compatibility; remove before release
|
||||
if (podStateManager.isPodInitialized() &&
|
||||
podStateManager.getActivationProgress() == ActivationProgress.NONE &&
|
||||
podStateManager.getPodProgressStatus().isAtLeast(PodProgressStatus.ABOVE_FIFTY_UNITS)) {
|
||||
podStateManager.setActivationProgress(ActivationProgress.COMPLETED);
|
||||
}
|
||||
|
||||
lastConnectionTimeMillis = sp.getLong(
|
||||
RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L);
|
||||
|
||||
|
@ -922,7 +930,7 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
|
|||
}
|
||||
|
||||
private void initializeAfterRileyLinkConnection() {
|
||||
if (podStateManager.isPodInitialized() && podStateManager.getPodProgressStatus().isAtLeast(PodProgressStatus.PAIRING_COMPLETED)) {
|
||||
if (podStateManager.getActivationProgress().isAtLeast(ActivationProgress.PAIRING_COMPLETED)) {
|
||||
for (int i = 0; STARTUP_STATUS_REQUEST_TRIES > i; i++) {
|
||||
PumpEnactResult result = executeCommand(OmnipodCommandType.GET_POD_STATUS, aapsOmnipodManager::getPodStatus);
|
||||
if (result.success) {
|
||||
|
|
|
@ -5,40 +5,45 @@ import org.joda.time.DateTimeZone;
|
|||
import java.util.Collections;
|
||||
import java.util.Random;
|
||||
|
||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.OmnipodMessage;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.AssignAddressCommand;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.VersionResponse;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PacketType;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalMessageAddressException;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPacketTypeException;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalVersionResponseTypeException;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager;
|
||||
|
||||
public class AssignAddressAction implements OmnipodAction<VersionResponse> {
|
||||
public class AssignAddressAction implements OmnipodAction<Void> {
|
||||
private final PodStateManager podStateManager;
|
||||
private final AAPSLogger aapsLogger;
|
||||
|
||||
public AssignAddressAction(PodStateManager podStateManager) {
|
||||
public AssignAddressAction(PodStateManager podStateManager, AAPSLogger aapsLogger) {
|
||||
if (podStateManager == null) {
|
||||
throw new IllegalArgumentException("podStateManager can not be null");
|
||||
}
|
||||
if (aapsLogger == null) {
|
||||
throw new IllegalArgumentException("Logger can not be null");
|
||||
}
|
||||
this.podStateManager = podStateManager;
|
||||
this.aapsLogger = aapsLogger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VersionResponse execute(OmnipodRileyLinkCommunicationManager communicationService) {
|
||||
public Void execute(OmnipodRileyLinkCommunicationManager communicationService) {
|
||||
if (!podStateManager.hasPodState()) {
|
||||
podStateManager.initState(generateRandomAddress());
|
||||
}
|
||||
if (podStateManager.isPodInitialized() && podStateManager.getPodProgressStatus().isAfter(PodProgressStatus.REMINDER_INITIALIZED)) {
|
||||
throw new IllegalPodProgressException(PodProgressStatus.REMINDER_INITIALIZED, podStateManager.getPodProgressStatus());
|
||||
}
|
||||
|
||||
if (podStateManager.getActivationProgress().needsPairing()) {
|
||||
AssignAddressCommand assignAddress = new AssignAddressCommand(podStateManager.getAddress());
|
||||
OmnipodMessage assignAddressMessage = new OmnipodMessage(OmnipodConstants.DEFAULT_ADDRESS,
|
||||
Collections.singletonList(assignAddress), podStateManager.getMessageNumber());
|
||||
|
||||
try {
|
||||
VersionResponse assignAddressResponse = communicationService.exchangeMessages(VersionResponse.class, podStateManager, assignAddressMessage,
|
||||
OmnipodConstants.DEFAULT_ADDRESS, podStateManager.getAddress());
|
||||
|
||||
|
@ -51,8 +56,17 @@ public class AssignAddressAction implements OmnipodAction<VersionResponse> {
|
|||
|
||||
podStateManager.setInitializationParameters(assignAddressResponse.getLot(), assignAddressResponse.getTid(), //
|
||||
assignAddressResponse.getPiVersion(), assignAddressResponse.getPmVersion(), DateTimeZone.getDefault(), assignAddressResponse.getPodProgressStatus());
|
||||
} catch (IllegalPacketTypeException ex) {
|
||||
if (ex.getActual() == PacketType.ACK && podStateManager.isPodInitialized()) {
|
||||
// When we already assigned the address before, it's possible to only get an ACK here
|
||||
aapsLogger.debug("Received ACK instead of response in AssignAddressAction. Ignoring because we already assigned the address successfully");
|
||||
} else {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return assignAddressResponse;
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int generateRandomAddress() {
|
||||
|
|
|
@ -6,16 +6,15 @@ import java.util.List;
|
|||
import java.util.Optional;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.service.ExpirationReminderBuilder;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.ActivationProgress;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertConfiguration;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalSchedule;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalActivationProgressException;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager;
|
||||
|
||||
public class InsertCannulaAction implements OmnipodAction<StatusResponse> {
|
||||
public class InsertCannulaAction implements OmnipodAction<Void> {
|
||||
|
||||
private final PodStateManager podStateManager;
|
||||
private final BasalSchedule initialBasalSchedule;
|
||||
|
@ -37,31 +36,33 @@ public class InsertCannulaAction implements OmnipodAction<StatusResponse> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public StatusResponse execute(OmnipodRileyLinkCommunicationManager communicationService) {
|
||||
if (!podStateManager.isPodInitialized() || podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.PRIMING_COMPLETED)) {
|
||||
throw new IllegalPodProgressException(PodProgressStatus.PRIMING_COMPLETED, podStateManager.isPodInitialized() ? podStateManager.getPodProgressStatus() : null);
|
||||
public Void execute(OmnipodRileyLinkCommunicationManager communicationService) {
|
||||
if (podStateManager.getActivationProgress().isBefore(ActivationProgress.PRIMING_COMPLETED)) {
|
||||
throw new IllegalActivationProgressException(ActivationProgress.PRIMING_COMPLETED, podStateManager.getActivationProgress());
|
||||
}
|
||||
|
||||
if (podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.BASAL_INITIALIZED)) {
|
||||
if (podStateManager.getActivationProgress().needsBasalSchedule()) {
|
||||
podStateManager.setBasalSchedule(initialBasalSchedule);
|
||||
communicationService.executeAction(new SetBasalScheduleAction(podStateManager, initialBasalSchedule,
|
||||
true, podStateManager.getScheduleOffset(), false));
|
||||
podStateManager.setActivationProgress(ActivationProgress.BASAL_INITIALIZED);
|
||||
}
|
||||
|
||||
if (podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.INSERTING_CANNULA)) {
|
||||
if (podStateManager.getActivationProgress().needsExpirationReminders()) {
|
||||
communicationService.executeAction(new ConfigureAlertsAction(podStateManager, buildAlertConfigurations()));
|
||||
|
||||
podStateManager.setExpirationAlertTimeBeforeShutdown(expirationReminderTimeBeforeShutdown);
|
||||
podStateManager.setLowReservoirAlertUnits(lowReservoirAlertUnits);
|
||||
|
||||
return communicationService.executeAction(new BolusAction(podStateManager, OmnipodConstants.POD_CANNULA_INSERTION_BOLUS_UNITS,
|
||||
Duration.standardSeconds(1), false, false));
|
||||
} else if (podStateManager.getPodProgressStatus().equals(PodProgressStatus.INSERTING_CANNULA)) {
|
||||
// Check status
|
||||
return communicationService.executeAction(new GetStatusAction(podStateManager));
|
||||
} else {
|
||||
throw new IllegalPodProgressException(null, podStateManager.getPodProgressStatus());
|
||||
podStateManager.setActivationProgress(ActivationProgress.EXPIRATION_REMINDERS_SET);
|
||||
}
|
||||
|
||||
if (podStateManager.getActivationProgress().needsCannulaInsertion()) {
|
||||
communicationService.executeAction(new BolusAction(podStateManager, OmnipodConstants.POD_CANNULA_INSERTION_BOLUS_UNITS,
|
||||
Duration.standardSeconds(1), false, false));
|
||||
podStateManager.setActivationProgress(ActivationProgress.INSERTING_CANNULA);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<AlertConfiguration> buildAlertConfigurations() {
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.service.PrimeService;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.ActivationProgress;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalActivationProgressException;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager;
|
||||
|
||||
public class PrimeAction implements OmnipodAction<StatusResponse> {
|
||||
public class PrimeAction implements OmnipodAction<Void> {
|
||||
|
||||
private final PrimeService service;
|
||||
private final PodStateManager podStateManager;
|
||||
|
@ -24,21 +23,27 @@ public class PrimeAction implements OmnipodAction<StatusResponse> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public StatusResponse execute(OmnipodRileyLinkCommunicationManager communicationService) {
|
||||
if (!podStateManager.isPodInitialized() || podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.PAIRING_COMPLETED)) {
|
||||
throw new IllegalPodProgressException(PodProgressStatus.PAIRING_COMPLETED, podStateManager.isPodInitialized() ? podStateManager.getPodProgressStatus() : null);
|
||||
public Void execute(OmnipodRileyLinkCommunicationManager communicationService) {
|
||||
if (podStateManager.getActivationProgress().isBefore(ActivationProgress.PAIRING_COMPLETED)) {
|
||||
throw new IllegalActivationProgressException(ActivationProgress.PAIRING_COMPLETED, podStateManager.getActivationProgress());
|
||||
}
|
||||
if (podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.PRIMING)) {
|
||||
|
||||
if (podStateManager.getActivationProgress().needsDisableTab5Sub16And17()) {
|
||||
// FaultConfigCommand sets internal pod variables to effectively disable $6x faults which occur more often with a 0 TBR
|
||||
service.executeDisableTab5Sub16And17FaultConfigCommand(communicationService, podStateManager);
|
||||
|
||||
service.executeFinishSetupReminderAlertCommand(communicationService, podStateManager);
|
||||
return service.executePrimeBolusCommand(communicationService, podStateManager);
|
||||
} else if (podStateManager.getPodProgressStatus().equals(PodProgressStatus.PRIMING)) {
|
||||
// Check status
|
||||
return communicationService.executeAction(new GetStatusAction(podStateManager));
|
||||
} else {
|
||||
throw new IllegalPodProgressException(null, podStateManager.getPodProgressStatus());
|
||||
podStateManager.setActivationProgress(ActivationProgress.TAB_5_SUB_16_AND_17_DISABLED);
|
||||
}
|
||||
|
||||
if (podStateManager.getActivationProgress().needsSetupReminders()) {
|
||||
service.executeFinishSetupReminderAlertCommand(communicationService, podStateManager);
|
||||
podStateManager.setActivationProgress(ActivationProgress.SETUP_REMINDERS_SET);
|
||||
}
|
||||
|
||||
if (podStateManager.getActivationProgress().needsPriming()) {
|
||||
service.executePrimeBolusCommand(communicationService, podStateManager);
|
||||
podStateManager.setActivationProgress(ActivationProgress.PRIMING);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,40 +4,52 @@ import org.joda.time.DateTime;
|
|||
|
||||
import java.util.Collections;
|
||||
|
||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.OmnipodMessage;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.SetupPodCommand;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.VersionResponse;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.ActivationProgress;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PacketType;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalMessageAddressException;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPacketTypeException;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalVersionResponseTypeException;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager;
|
||||
|
||||
public class SetupPodAction implements OmnipodAction<VersionResponse> {
|
||||
public class SetupPodAction implements OmnipodAction<Void> {
|
||||
private final PodStateManager podStateManager;
|
||||
private final AAPSLogger aapsLogger;
|
||||
|
||||
public SetupPodAction(PodStateManager podStateManager) {
|
||||
public SetupPodAction(PodStateManager podStateManager, AAPSLogger aapsLogger) {
|
||||
if (podStateManager == null) {
|
||||
throw new IllegalArgumentException("Pod state manager can not be null");
|
||||
}
|
||||
if (aapsLogger == null) {
|
||||
throw new IllegalArgumentException("Logger can not be null");
|
||||
}
|
||||
this.podStateManager = podStateManager;
|
||||
this.aapsLogger = aapsLogger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VersionResponse execute(OmnipodRileyLinkCommunicationManager communicationService) {
|
||||
if (!podStateManager.isPodInitialized() || !podStateManager.getPodProgressStatus().equals(PodProgressStatus.REMINDER_INITIALIZED)) {
|
||||
public Void execute(OmnipodRileyLinkCommunicationManager communicationService) {
|
||||
if (!podStateManager.isPodInitialized()) {
|
||||
throw new IllegalPodProgressException(PodProgressStatus.REMINDER_INITIALIZED, podStateManager.isPodInitialized() ? podStateManager.getPodProgressStatus() : null);
|
||||
}
|
||||
|
||||
if (podStateManager.getActivationProgress().needsPairing()) {
|
||||
DateTime activationDate = DateTime.now(podStateManager.getTimeZone());
|
||||
|
||||
SetupPodCommand setupPodCommand = new SetupPodCommand(podStateManager.getAddress(), activationDate,
|
||||
podStateManager.getLot(), podStateManager.getTid());
|
||||
OmnipodMessage message = new OmnipodMessage(OmnipodConstants.DEFAULT_ADDRESS,
|
||||
Collections.singletonList(setupPodCommand), podStateManager.getMessageNumber());
|
||||
VersionResponse setupPodResponse;
|
||||
setupPodResponse = communicationService.exchangeMessages(VersionResponse.class, podStateManager,
|
||||
|
||||
try {
|
||||
VersionResponse setupPodResponse = communicationService.exchangeMessages(VersionResponse.class, podStateManager,
|
||||
message, OmnipodConstants.DEFAULT_ADDRESS, podStateManager.getAddress());
|
||||
|
||||
if (!setupPodResponse.isSetupPodVersionResponse()) {
|
||||
|
@ -46,7 +58,18 @@ public class SetupPodAction implements OmnipodAction<VersionResponse> {
|
|||
if (setupPodResponse.getAddress() != podStateManager.getAddress()) {
|
||||
throw new IllegalMessageAddressException(podStateManager.getAddress(), setupPodResponse.getAddress());
|
||||
}
|
||||
} catch (IllegalPacketTypeException ex) {
|
||||
if (PacketType.ACK.equals(ex.getActual())) {
|
||||
// Pod is already configured
|
||||
aapsLogger.debug("Received ACK instead of response in SetupPodAction. Ignoring");
|
||||
} else {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
return setupPodResponse;
|
||||
podStateManager.setActivationProgress(ActivationProgress.PAIRING_COMPLETED);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 +
|
||||
|
|
|
@ -3,7 +3,6 @@ package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.mes
|
|||
import org.joda.time.Duration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
|
||||
|
@ -54,7 +53,7 @@ public class PodInfoActiveAlerts extends PodInfo {
|
|||
@Override
|
||||
public String toString() {
|
||||
return "PodInfoActiveAlerts{" +
|
||||
"word278=" + Arrays.toString(word278) +
|
||||
"word278=" + ByteUtil.shortHexString(word278) +
|
||||
", alertActivations=" + alertActivations +
|
||||
'}';
|
||||
}
|
||||
|
|
|
@ -6,13 +6,13 @@ 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.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;
|
||||
|
||||
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;
|
||||
|
@ -27,14 +27,13 @@ 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 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) {
|
||||
|
@ -69,27 +68,33 @@ 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));
|
||||
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() {
|
||||
|
@ -140,12 +145,8 @@ public class PodInfoFaultEvent extends PodInfo implements StatusUpdatableRespons
|
|||
return faultAccessingTables;
|
||||
}
|
||||
|
||||
public LogEventErrorCode getLogEventErrorType() {
|
||||
return logEventErrorType;
|
||||
}
|
||||
|
||||
public PodProgressStatus getLogEventErrorPodProgressStatus() {
|
||||
return logEventErrorPodProgressStatus;
|
||||
public ErrorEventInfo getErrorEventInfo() {
|
||||
return errorEventInfo;
|
||||
}
|
||||
|
||||
public byte getReceiverLowGain() {
|
||||
|
@ -156,8 +157,8 @@ public class PodInfoFaultEvent extends PodInfo implements StatusUpdatableRespons
|
|||
return radioRSSI;
|
||||
}
|
||||
|
||||
public PodProgressStatus getPodProgressStatusAtTimeOfFirstLoggedFaultEvent() {
|
||||
return podProgressStatusAtTimeOfFirstLoggedFaultEvent;
|
||||
public PodProgressStatus getPreviousPodProgressStatus() {
|
||||
return previousPodProgressStatus;
|
||||
}
|
||||
|
||||
public byte[] getUnknownValue() {
|
||||
|
@ -165,7 +166,7 @@ public class PodInfoFaultEvent extends PodInfo implements StatusUpdatableRespons
|
|||
}
|
||||
|
||||
@Override public String toString() {
|
||||
return "PodInfoFaultEvent{" +
|
||||
return "PodInfoDetailedStatus{" +
|
||||
"podProgressStatus=" + podProgressStatus +
|
||||
", deliveryStatus=" + deliveryStatus +
|
||||
", bolusNotDelivered=" + bolusNotDelivered +
|
||||
|
@ -178,11 +179,10 @@ public class PodInfoFaultEvent extends PodInfo implements StatusUpdatableRespons
|
|||
", timeActive=" + timeActive +
|
||||
", unacknowledgedAlerts=" + unacknowledgedAlerts +
|
||||
", faultAccessingTables=" + faultAccessingTables +
|
||||
", logEventErrorType=" + logEventErrorType +
|
||||
", logEventErrorPodProgressStatus=" + logEventErrorPodProgressStatus +
|
||||
", errorEventInfo=" + errorEventInfo +
|
||||
", receiverLowGain=" + receiverLowGain +
|
||||
", radioRSSI=" + radioRSSI +
|
||||
", podProgressStatusAtTimeOfFirstLoggedFaultEvent=" + podProgressStatusAtTimeOfFirstLoggedFaultEvent +
|
||||
", previousPodProgressStatus=" + previousPodProgressStatus +
|
||||
", unknownValue=" + ByteUtil.shortHexString(unknownValue) +
|
||||
'}';
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition;
|
||||
|
||||
public enum ActivationProgress {
|
||||
NONE,
|
||||
PAIRING_COMPLETED,
|
||||
TAB_5_SUB_16_AND_17_DISABLED,
|
||||
SETUP_REMINDERS_SET,
|
||||
PRIMING,
|
||||
PRIMING_COMPLETED,
|
||||
BASAL_INITIALIZED,
|
||||
EXPIRATION_REMINDERS_SET,
|
||||
INSERTING_CANNULA,
|
||||
COMPLETED;
|
||||
|
||||
public boolean needsPairing() {
|
||||
return this == NONE;
|
||||
}
|
||||
|
||||
public boolean needsDisableTab5Sub16And17() {
|
||||
return this == PAIRING_COMPLETED;
|
||||
}
|
||||
|
||||
public boolean needsSetupReminders() {
|
||||
return this == TAB_5_SUB_16_AND_17_DISABLED;
|
||||
}
|
||||
|
||||
public boolean needsPriming() {
|
||||
return this == SETUP_REMINDERS_SET;
|
||||
}
|
||||
|
||||
public boolean needsPrimingVerification() {
|
||||
return this == PRIMING;
|
||||
}
|
||||
|
||||
public boolean needsBasalSchedule() {
|
||||
return this == PRIMING_COMPLETED;
|
||||
}
|
||||
|
||||
public boolean needsExpirationReminders() {
|
||||
return this == BASAL_INITIALIZED;
|
||||
}
|
||||
|
||||
public boolean needsCannulaInsertion() {
|
||||
return this == EXPIRATION_REMINDERS_SET;
|
||||
}
|
||||
|
||||
public boolean needsCannulaInsertionVerification() {
|
||||
return this == INSERTING_CANNULA;
|
||||
}
|
||||
|
||||
public boolean isCompleted() {
|
||||
return this == COMPLETED;
|
||||
}
|
||||
|
||||
public boolean isBefore(ActivationProgress other) {
|
||||
return ordinal() < other.ordinal();
|
||||
}
|
||||
|
||||
public boolean isAtLeast(ActivationProgress other) {
|
||||
return ordinal() >= other.ordinal();
|
||||
}
|
||||
|
||||
public boolean isAfter(ActivationProgress other) {
|
||||
return ordinal() > other.ordinal();
|
||||
}
|
||||
}
|
|
@ -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 +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.ActivationProgress;
|
||||
|
||||
public class IllegalActivationProgressException extends OmnipodException {
|
||||
private final ActivationProgress expected;
|
||||
private final ActivationProgress actual;
|
||||
|
||||
public IllegalActivationProgressException(ActivationProgress expected, ActivationProgress actual) {
|
||||
super(String.format(Locale.getDefault(), "Illegal activation progress: %s, expected: %s", actual, expected), true);
|
||||
this.expected = expected;
|
||||
this.actual = actual;
|
||||
}
|
||||
|
||||
public ActivationProgress getExpected() {
|
||||
return expected;
|
||||
}
|
||||
|
||||
public ActivationProgress getActual() {
|
||||
return actual;
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@ public class IllegalPodProgressException extends OmnipodException {
|
|||
private final PodProgressStatus actual;
|
||||
|
||||
public IllegalPodProgressException(PodProgressStatus expected, PodProgressStatus actual) {
|
||||
super(String.format(Locale.getDefault(), "Illegal setup state: %s, expected: %s", actual, expected), true);
|
||||
super(String.format(Locale.getDefault(), "Illegal Pod progress: %s, expected: %s", actual, expected), true);
|
||||
this.expected = expected;
|
||||
this.actual = actual;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,19 +31,19 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.mess
|
|||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoRecentPulseLog;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoResponse;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.ActivationProgress;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertConfiguration;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.BeepType;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryStatus;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryType;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PacketType;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalSchedule;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.CommandFailedAfterChangingDeliveryStatusException;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.DeliveryStatusVerificationFailedException;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalActivationProgressException;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalDeliveryStatusException;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPacketTypeException;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.NonceOutOfSyncException;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.OmnipodException;
|
||||
|
@ -59,7 +59,7 @@ import io.reactivex.schedulers.Schedulers;
|
|||
import io.reactivex.subjects.SingleSubject;
|
||||
|
||||
public class OmnipodManager {
|
||||
private static final int ACTION_VERIFICATION_TRIES = 2;
|
||||
private static final int ACTION_VERIFICATION_TRIES = 1;
|
||||
|
||||
private final OmnipodRileyLinkCommunicationManager communicationService;
|
||||
private PodStateManager podStateManager;
|
||||
|
@ -88,76 +88,53 @@ public class OmnipodManager {
|
|||
}
|
||||
|
||||
public synchronized Single<Boolean> pairAndPrime() {
|
||||
logStartingCommandExecution("pairAndPrime");
|
||||
if (podStateManager.isPodInitialized()) {
|
||||
if (podStateManager.getActivationProgress().isAfter(ActivationProgress.PRIMING)) {
|
||||
return Single.just(true);
|
||||
}
|
||||
if (podStateManager.getActivationProgress().needsPrimingVerification()) {
|
||||
return Single.fromCallable(() -> verifyPodProgressStatus(PodProgressStatus.PRIMING_COMPLETED, ActivationProgress.PRIMING_COMPLETED));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (!podStateManager.isPodInitialized() || podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.PAIRING_COMPLETED)) {
|
||||
// Always send both 0x07 and 0x03 on retries
|
||||
try {
|
||||
if (podStateManager.getActivationProgress().isBefore(ActivationProgress.PAIRING_COMPLETED)) {
|
||||
communicationService.executeAction(
|
||||
new AssignAddressAction(podStateManager));
|
||||
} catch (IllegalPacketTypeException ex) {
|
||||
if (ex.getActual() == PacketType.ACK && podStateManager.isPodInitialized()) {
|
||||
// When we already assigned the address before, it's possible to only get an ACK here
|
||||
aapsLogger.debug("Received ACK instead of response in AssignAddressAction. Ignoring because we already assigned the address successfully");
|
||||
} else {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
new AssignAddressAction(podStateManager, aapsLogger));
|
||||
|
||||
try {
|
||||
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");
|
||||
communicationService.executeAction(new SetupPodAction(podStateManager, aapsLogger));
|
||||
}
|
||||
}
|
||||
} else if (podStateManager.getPodProgressStatus().isAfter(PodProgressStatus.PRIMING)) {
|
||||
throw new IllegalPodProgressException(PodProgressStatus.PAIRING_COMPLETED, podStateManager.getPodProgressStatus());
|
||||
}
|
||||
|
||||
// Make sure we have an up to date PodProgressStatus
|
||||
getPodStatus();
|
||||
|
||||
communicationService.executeAction(new PrimeAction(new PrimeService(), podStateManager));
|
||||
} 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)) //
|
||||
.map(o -> verifyPodProgressStatus(PodProgressStatus.PRIMING_COMPLETED, ActivationProgress.PRIMING_COMPLETED)) //
|
||||
.subscribeOn(Schedulers.io());
|
||||
}
|
||||
|
||||
public synchronized Single<Boolean> insertCannula(
|
||||
BasalSchedule basalSchedule, Duration expirationReminderTimeBeforeShutdown, Integer lowReservoirAlertUnits) {
|
||||
if (!podStateManager.isPodInitialized() || podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.PRIMING_COMPLETED)) {
|
||||
throw new IllegalPodProgressException(PodProgressStatus.PRIMING_COMPLETED, !podStateManager.isPodInitialized() ? null : podStateManager.getPodProgressStatus());
|
||||
if (podStateManager.getActivationProgress().isBefore(ActivationProgress.PRIMING_COMPLETED)) {
|
||||
throw new IllegalActivationProgressException(ActivationProgress.PRIMING_COMPLETED, podStateManager.getActivationProgress());
|
||||
}
|
||||
|
||||
// Make sure we have the latest PodProgressStatus
|
||||
getPodStatus();
|
||||
|
||||
if (podStateManager.getPodProgressStatus().isAfter(PodProgressStatus.INSERTING_CANNULA)) {
|
||||
throw new IllegalPodProgressException(PodProgressStatus.PRIMING_COMPLETED, podStateManager.getPodProgressStatus());
|
||||
if (podStateManager.isPodInitialized()) {
|
||||
if (podStateManager.getActivationProgress().isCompleted()) {
|
||||
return Single.just(true);
|
||||
}
|
||||
if (podStateManager.getActivationProgress().needsCannulaInsertionVerification()) {
|
||||
return Single.fromCallable(() -> verifyPodProgressStatus(PodProgressStatus.ABOVE_FIFTY_UNITS, ActivationProgress.COMPLETED));
|
||||
}
|
||||
}
|
||||
|
||||
logStartingCommandExecution("insertCannula [basalSchedule=" + basalSchedule + "]");
|
||||
|
||||
try {
|
||||
communicationService.executeAction(new InsertCannulaAction(podStateManager, basalSchedule, expirationReminderTimeBeforeShutdown, lowReservoirAlertUnits));
|
||||
} 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)) //
|
||||
.map(o -> verifyPodProgressStatus(PodProgressStatus.ABOVE_FIFTY_UNITS, ActivationProgress.COMPLETED)) //
|
||||
.subscribeOn(Schedulers.io());
|
||||
}
|
||||
|
||||
|
@ -166,49 +143,29 @@ public class OmnipodManager {
|
|||
throw new IllegalPodProgressException(PodProgressStatus.REMINDER_INITIALIZED, null);
|
||||
}
|
||||
|
||||
logStartingCommandExecution("getPodStatus");
|
||||
|
||||
try {
|
||||
return communicationService.executeAction(new GetStatusAction(podStateManager));
|
||||
} finally {
|
||||
logCommandExecutionFinished("getPodStatus");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public synchronized PodInfoResponse getPodInfo(PodInfoType podInfoType) {
|
||||
assertReadyForDelivery();
|
||||
|
||||
logStartingCommandExecution("getPodInfo");
|
||||
|
||||
try {
|
||||
return communicationService.executeAction(new GetPodInfoAction(podStateManager, podInfoType));
|
||||
} finally {
|
||||
logCommandExecutionFinished("getPodInfo");
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized StatusResponse configureAlerts(List<AlertConfiguration> alertConfigurations) {
|
||||
assertReadyForDelivery();
|
||||
logStartingCommandExecution("configureAlerts");
|
||||
try {
|
||||
|
||||
StatusResponse statusResponse = executeAndVerify(() -> communicationService.executeAction(new ConfigureAlertsAction(podStateManager, alertConfigurations)));
|
||||
ConfigureAlertsAction.updateConfiguredAlerts(podStateManager, alertConfigurations);
|
||||
return statusResponse;
|
||||
} finally {
|
||||
logCommandExecutionFinished("configureAlerts");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public synchronized StatusResponse acknowledgeAlerts() {
|
||||
assertReadyForDelivery();
|
||||
|
||||
logStartingCommandExecution("acknowledgeAlerts");
|
||||
|
||||
try {
|
||||
return executeAndVerify(() -> communicationService.executeAction(new AcknowledgeAlertsAction(podStateManager, podStateManager.getActiveAlerts())));
|
||||
} finally {
|
||||
logCommandExecutionFinished("acknowledgeAlerts");
|
||||
}
|
||||
}
|
||||
|
||||
// CAUTION: cancels all delivery
|
||||
|
@ -216,9 +173,6 @@ public class OmnipodManager {
|
|||
public synchronized void setBasalSchedule(BasalSchedule schedule, boolean acknowledgementBeep) {
|
||||
assertReadyForDelivery();
|
||||
|
||||
logStartingCommandExecution("setBasalSchedule [basalSchedule=" + schedule + ", acknowledgementBeep=" + acknowledgementBeep + "]");
|
||||
|
||||
try {
|
||||
boolean wasSuspended = podStateManager.isSuspended();
|
||||
if (!wasSuspended) {
|
||||
suspendDelivery(acknowledgementBeep);
|
||||
|
@ -247,22 +201,14 @@ public class OmnipodManager {
|
|||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} finally {
|
||||
logCommandExecutionFinished("setBasalSchedule");
|
||||
}
|
||||
}
|
||||
|
||||
// CAUTION: cancels temp basal and then sets new temp basal. An OmnipodException[certainFailure=false] indicates that the pod might have cancelled the previous temp basal, but did not set a new temp basal
|
||||
public synchronized void setTemporaryBasal(double rate, Duration duration, boolean acknowledgementBeep, boolean completionBeep) {
|
||||
assertReadyForDelivery();
|
||||
|
||||
logStartingCommandExecution("setTemporaryBasal [rate=" + rate + ", duration=" + duration + ", acknowledgementBeep=" + acknowledgementBeep + ", completionBeep=" + completionBeep + "]");
|
||||
|
||||
boolean cancelCurrentTbr = podStateManager.isTempBasalRunning();
|
||||
|
||||
try {
|
||||
if (cancelCurrentTbr) {
|
||||
try {
|
||||
cancelDelivery(EnumSet.of(DeliveryType.TEMP_BASAL), acknowledgementBeep);
|
||||
|
@ -320,9 +266,6 @@ public class OmnipodManager {
|
|||
throw ex2;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
logCommandExecutionFinished("setTemporaryBasal");
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void cancelTemporaryBasal(boolean acknowledgementBeep) {
|
||||
|
@ -348,17 +291,11 @@ public class OmnipodManager {
|
|||
private synchronized StatusResponse cancelDelivery(EnumSet<DeliveryType> deliveryTypes, boolean acknowledgementBeep) {
|
||||
assertReadyForDelivery();
|
||||
|
||||
logStartingCommandExecution("cancelDelivery [deliveryTypes=" + deliveryTypes + ", acknowledgementBeep=" + acknowledgementBeep + "]");
|
||||
|
||||
try {
|
||||
return executeAndVerify(() -> {
|
||||
StatusResponse statusResponse = communicationService.executeAction(new CancelDeliveryAction(podStateManager, deliveryTypes, acknowledgementBeep));
|
||||
aapsLogger.info(LTag.PUMPCOMM, "Status response after cancel delivery[types={}]: {}", deliveryTypes.toString(), statusResponse.toString());
|
||||
return statusResponse;
|
||||
});
|
||||
} finally {
|
||||
logCommandExecutionFinished("cancelDelivery");
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a SingleSubject that returns when the bolus has finished.
|
||||
|
@ -367,8 +304,6 @@ public class OmnipodManager {
|
|||
public synchronized BolusCommandResult bolus(Double units, boolean acknowledgementBeep, boolean completionBeep, BiConsumer<Double, Integer> progressIndicationConsumer) {
|
||||
assertReadyForDelivery();
|
||||
|
||||
logStartingCommandExecution("bolus [units=" + units + ", acknowledgementBeep=" + acknowledgementBeep + ", completionBeep=" + completionBeep + "]");
|
||||
|
||||
bolusCommandExecutionSubject = SingleSubject.create();
|
||||
|
||||
CommandDeliveryStatus commandDeliveryStatus = CommandDeliveryStatus.SUCCESS;
|
||||
|
@ -437,7 +372,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;
|
||||
|
@ -454,8 +389,6 @@ public class OmnipodManager {
|
|||
})
|
||||
.subscribe());
|
||||
|
||||
logCommandExecutionFinished("bolus");
|
||||
|
||||
return new BolusCommandResult(commandDeliveryStatus, bolusCompletionSubject);
|
||||
}
|
||||
|
||||
|
@ -467,16 +400,12 @@ public class OmnipodManager {
|
|||
throw new IllegalDeliveryStatusException(DeliveryStatus.BOLUS_IN_PROGRESS, podStateManager.getLastDeliveryStatus());
|
||||
}
|
||||
|
||||
logStartingCommandExecution("cancelBolus [acknowledgementBeep=" + acknowledgementBeep + "]");
|
||||
|
||||
try {
|
||||
StatusResponse statusResponse = cancelDelivery(EnumSet.of(DeliveryType.BOLUS), acknowledgementBeep);
|
||||
discardActiveBolusData(statusResponse.getBolusNotDelivered());
|
||||
} catch (PodFaultException ex) {
|
||||
discardActiveBolusData(ex.getFaultEvent().getBolusNotDelivered());
|
||||
discardActiveBolusData(ex.getDetailedStatus().getBolusNotDelivered());
|
||||
throw ex;
|
||||
} finally {
|
||||
logCommandExecutionFinished("cancelBolus");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -494,7 +423,6 @@ public class OmnipodManager {
|
|||
public synchronized void suspendDelivery(boolean acknowledgementBeep) {
|
||||
assertReadyForDelivery();
|
||||
|
||||
logStartingCommandExecution("suspendDelivery");
|
||||
|
||||
try {
|
||||
cancelDelivery(EnumSet.allOf(DeliveryType.class), acknowledgementBeep);
|
||||
|
@ -508,8 +436,6 @@ public class OmnipodManager {
|
|||
ex.setCertainFailure(true);
|
||||
throw ex;
|
||||
}
|
||||
} finally {
|
||||
logCommandExecutionFinished("suspendDelivery");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -518,9 +444,6 @@ public class OmnipodManager {
|
|||
public synchronized void setTime(boolean acknowledgementBeeps) {
|
||||
assertReadyForDelivery();
|
||||
|
||||
logStartingCommandExecution("setTime [acknowledgementBeeps=" + acknowledgementBeeps + "]");
|
||||
|
||||
try {
|
||||
DateTimeZone oldTimeZone = podStateManager.getTimeZone();
|
||||
|
||||
try {
|
||||
|
@ -535,9 +458,6 @@ public class OmnipodManager {
|
|||
}
|
||||
|
||||
podStateManager.updateActivatedAt();
|
||||
} finally {
|
||||
logCommandExecutionFinished("setTime");
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void deactivatePod() {
|
||||
|
@ -545,8 +465,6 @@ public class OmnipodManager {
|
|||
throw new IllegalPodProgressException(PodProgressStatus.REMINDER_INITIALIZED, null);
|
||||
}
|
||||
|
||||
logStartingCommandExecution("deactivatePod");
|
||||
|
||||
// Try to get pulse log for diagnostics
|
||||
try {
|
||||
PodInfoResponse podInfoResponse = communicationService.executeAction(new GetPodInfoAction(podStateManager, PodInfoType.RECENT_PULSE_LOG));
|
||||
|
@ -561,8 +479,6 @@ public class OmnipodManager {
|
|||
communicationService.executeAction(new DeactivatePodAction(podStateManager, true));
|
||||
} catch (PodFaultException ex) {
|
||||
aapsLogger.info(LTag.PUMPCOMM, "Ignoring PodFaultException in deactivatePod", ex);
|
||||
} finally {
|
||||
logCommandExecutionFinished("deactivatePod");
|
||||
}
|
||||
|
||||
podStateManager.discardState();
|
||||
|
@ -592,7 +508,6 @@ public class OmnipodManager {
|
|||
|
||||
// Only works for commands with nonce resyncable message blocks
|
||||
private StatusResponse executeAndVerify(Supplier<StatusResponse> supplier) {
|
||||
logStartingCommandExecution("verifyCommand");
|
||||
try {
|
||||
return supplier.get();
|
||||
} catch (OmnipodException originalException) {
|
||||
|
@ -616,8 +531,6 @@ public class OmnipodManager {
|
|||
throw originalException;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
logCommandExecutionFinished("verifyCommand");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -632,7 +545,7 @@ public class OmnipodManager {
|
|||
* @return true if the Pod's progress status matches the expected status, otherwise false
|
||||
* @throws PodProgressStatusVerificationFailedException in case reading the Pod status fails
|
||||
*/
|
||||
private boolean verifyPodProgressStatus(PodProgressStatus expectedPodProgressStatus) {
|
||||
private boolean verifyPodProgressStatus(PodProgressStatus expectedPodProgressStatus, ActivationProgress activationProgress) {
|
||||
Boolean result = null;
|
||||
Throwable lastException = null;
|
||||
|
||||
|
@ -641,6 +554,7 @@ public class OmnipodManager {
|
|||
StatusResponse statusResponse = getPodStatus();
|
||||
|
||||
if (statusResponse.getPodProgressStatus().equals(expectedPodProgressStatus)) {
|
||||
podStateManager.setActivationProgress(activationProgress);
|
||||
return true;
|
||||
} else {
|
||||
result = false;
|
||||
|
@ -681,14 +595,6 @@ public class OmnipodManager {
|
|||
throw new DeliveryStatusVerificationFailedException(expectedStatus, verificationCause);
|
||||
}
|
||||
|
||||
private void logStartingCommandExecution(String action) {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "Starting command execution for action: " + action);
|
||||
}
|
||||
|
||||
private void logCommandExecutionFinished(String action) {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "Command execution finished for action: " + action);
|
||||
}
|
||||
|
||||
private Duration calculateEstimatedBolusDuration(DateTime startTime, double units, double deliveryRateInUnitsPerSecond) {
|
||||
if (!podStateManager.isPodActivationCompleted()) {
|
||||
// No basal or temp basal is active yet
|
||||
|
|
|
@ -16,16 +16,19 @@ import java.util.Arrays;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||
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.ActivationProgress;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertSet;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertSlot;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertType;
|
||||
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 +82,7 @@ public abstract class PodStateManager {
|
|||
* @return true if we have a Pod state and the Pod activation has been completed. The pod could also be dead at this point
|
||||
*/
|
||||
public final boolean isPodActivationCompleted() {
|
||||
return isPodInitialized() && podState.getPodProgressStatus().isAtLeast(PodProgressStatus.ABOVE_FIFTY_UNITS) && podState.getPodProgressStatus() != PodProgressStatus.ACTIVATION_TIME_EXCEEDED;
|
||||
return getActivationProgress().isCompleted();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -97,6 +100,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 +242,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) {
|
||||
|
@ -331,6 +337,17 @@ public abstract class PodStateManager {
|
|||
return activatedAt == null ? null : activatedAt.withZone(getSafe(() -> podState.getTimeZone())).plus(OmnipodConstants.NOMINAL_POD_LIFE);
|
||||
}
|
||||
|
||||
public final ActivationProgress getActivationProgress() {
|
||||
if (hasPodState()) {
|
||||
return Optional.ofNullable(podState.getActivationProgress()).orElse(ActivationProgress.NONE);
|
||||
}
|
||||
return ActivationProgress.NONE;
|
||||
}
|
||||
|
||||
public final void setActivationProgress(ActivationProgress activationProgress) {
|
||||
setAndStore(() -> podState.setActivationProgress(activationProgress));
|
||||
}
|
||||
|
||||
public final PodProgressStatus getPodProgressStatus() {
|
||||
return getSafe(() -> podState.getPodProgressStatus());
|
||||
}
|
||||
|
@ -513,20 +530,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 +552,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,11 +650,12 @@ 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;
|
||||
private NonceState nonceState;
|
||||
private ActivationProgress activationProgress = ActivationProgress.NONE;
|
||||
private PodProgressStatus podProgressStatus;
|
||||
private DeliveryStatus lastDeliveryStatus;
|
||||
private AlertSet activeAlerts;
|
||||
|
@ -751,12 +776,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() {
|
||||
|
@ -799,6 +824,14 @@ public abstract class PodStateManager {
|
|||
this.nonceState = nonceState;
|
||||
}
|
||||
|
||||
ActivationProgress getActivationProgress() {
|
||||
return activationProgress;
|
||||
}
|
||||
|
||||
void setActivationProgress(ActivationProgress activationProgress) {
|
||||
this.activationProgress = activationProgress;
|
||||
}
|
||||
|
||||
PodProgressStatus getPodProgressStatus() {
|
||||
return podProgressStatus;
|
||||
}
|
||||
|
@ -930,11 +963,12 @@ public abstract class PodStateManager {
|
|||
", timeZone=" + timeZone +
|
||||
", activatedAt=" + activatedAt +
|
||||
", timeActive=" + timeActive +
|
||||
", faultEvent=" + faultEvent +
|
||||
", faultEventCode=" + faultEventCode +
|
||||
", reservoirLevel=" + reservoirLevel +
|
||||
", totalTicksDelivered=" + totalTicksDelivered +
|
||||
", suspended=" + suspended +
|
||||
", nonceState=" + nonceState +
|
||||
", activationProgress=" + activationProgress +
|
||||
", podProgressStatus=" + podProgressStatus +
|
||||
", lastDeliveryStatus=" + lastDeliveryStatus +
|
||||
", activeAlerts=" + activeAlerts +
|
||||
|
|
|
@ -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;
|
||||
|
@ -62,6 +62,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalM
|
|||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPacketTypeException;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalResponseException;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalActivationProgressException;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalVersionResponseTypeException;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.MessageDecodingException;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.NonceOutOfSyncException;
|
||||
|
@ -758,11 +759,9 @@ 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)) {
|
||||
FaultEventCode faultEventCode = ((PodFaultException) ex).getDetailedStatus().getFaultEventCode();
|
||||
showPodFaultNotification(faultEventCode);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
aapsLogger.error(LTag.PUMP, "Caught an unexpected non-OmnipodException from OmnipodManager", ex);
|
||||
}
|
||||
|
@ -775,7 +774,8 @@ public class AapsOmnipodManager {
|
|||
comment = getStringResource(R.string.omnipod_error_crc_mismatch);
|
||||
} else if (ex instanceof IllegalPacketTypeException) {
|
||||
comment = getStringResource(R.string.omnipod_error_invalid_packet_type);
|
||||
} else if (ex instanceof IllegalPodProgressException || ex instanceof IllegalDeliveryStatusException) {
|
||||
} else if (ex instanceof IllegalPodProgressException || ex instanceof IllegalActivationProgressException ||
|
||||
ex instanceof IllegalDeliveryStatusException) {
|
||||
comment = getStringResource(R.string.omnipod_error_invalid_progress_state);
|
||||
} else if (ex instanceof IllegalVersionResponseTypeException) {
|
||||
comment = getStringResource(R.string.omnipod_error_invalid_response);
|
||||
|
@ -794,8 +794,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) {
|
||||
|
@ -816,9 +818,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());
|
||||
}
|
||||
|
|
|
@ -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
|
||||
} 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(faultEvent);
|
||||
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) {
|
||||
|
|
|
@ -23,6 +23,7 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyL
|
|||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodPumpPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.R
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.ActivationProgress
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager
|
||||
|
@ -272,8 +273,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,9 +346,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) {
|
||||
resourceHelper.gs(R.string.omnipod_pod_status_activation_time_exceeded)
|
||||
} else if (podStateManager.podProgressStatus.isBefore(PodProgressStatus.PRIMING_COMPLETED)) {
|
||||
if (podStateManager.activationProgress.isBefore(ActivationProgress.PRIMING_COMPLETED)) {
|
||||
resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_activation)
|
||||
} else {
|
||||
resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_cannula_insertion)
|
||||
|
@ -454,7 +453,7 @@ class OmnipodOverviewFragment : DaggerFragment() {
|
|||
}
|
||||
|
||||
private fun updateRefreshStatusButton() {
|
||||
omnipod_overview_button_refresh_status.isEnabled = podStateManager.isPodInitialized && podStateManager.podProgressStatus.isAtLeast(PodProgressStatus.PAIRING_COMPLETED)
|
||||
omnipod_overview_button_refresh_status.isEnabled = podStateManager.isPodInitialized && podStateManager.activationProgress.isAtLeast(ActivationProgress.PAIRING_COMPLETED)
|
||||
&& rileyLinkServiceData.rileyLinkServiceState.isReady && isQueueEmpty()
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
|||
import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.R
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.ActivationProgress
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.manager.AapsOmnipodManager
|
||||
|
@ -94,7 +95,7 @@ class PodManagementActivity : NoSplashAppCompatActivity() {
|
|||
|
||||
if (rileyLinkServiceData.rileyLinkServiceState.isReady) {
|
||||
omnipod_pod_management_button_activate_pod.isEnabled = !podStateManager.isPodActivationCompleted
|
||||
omnipod_pod_management_button_deactivate_pod.isEnabled = podStateManager.isPodInitialized
|
||||
omnipod_pod_management_button_deactivate_pod.isEnabled = podStateManager.activationProgress.isAtLeast(ActivationProgress.PAIRING_COMPLETED)
|
||||
if (discardButtonEnabled) {
|
||||
omnipod_pod_management_button_discard_pod.isEnabled = true
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.activation
|
|||
import android.os.Bundle
|
||||
import androidx.annotation.IdRes
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.R
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.ActivationProgress
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.common.activity.OmnipodWizardActivityBase
|
||||
import javax.inject.Inject
|
||||
|
@ -25,7 +25,7 @@ class PodActivationWizardActivity : OmnipodWizardActivityBase() {
|
|||
setContentView(R.layout.omnipod_pod_activation_wizard_activity)
|
||||
|
||||
startDestination = savedInstanceState?.getInt(KEY_START_DESTINATION, R.id.fillPodInfoFragment)
|
||||
?: if (!podStateManager.isPodInitialized || podStateManager.podProgressStatus.isBefore(PodProgressStatus.PRIMING_COMPLETED)) {
|
||||
?: if (podStateManager.activationProgress.isBefore(ActivationProgress.PRIMING_COMPLETED)) {
|
||||
R.id.fillPodInfoFragment
|
||||
} else {
|
||||
R.id.attachPodInfoFragment
|
||||
|
|
|
@ -3,8 +3,7 @@ package info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.activation.fra
|
|||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.R
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.ActivationProgress
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.common.fragment.ActionFragmentBase
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.deactivation.PodDeactivationWizardActivity
|
||||
|
@ -27,8 +26,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 && podStateManager.activationProgress.isAtLeast(ActivationProgress.PAIRING_COMPLETED)) {
|
||||
omnipod_wizard_button_retry.visibility = View.GONE
|
||||
omnipod_wizard_button_deactivate_pod.visibility = View.VISIBLE
|
||||
}
|
||||
|
|
|
@ -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<Object>() {
|
||||
@Override public void inject(Object instance) {}
|
||||
@Override public void inject(Object instance) {
|
||||
}
|
||||
});
|
||||
Profile profile = mock(Profile.class);
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -1,121 +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.LogEventErrorCode;
|
||||
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());
|
||||
assertEquals(LogEventErrorCode.NONE, podInfoFaultEvent.getLogEventErrorType());
|
||||
assertEquals(PodProgressStatus.INACTIVE, podInfoFaultEvent.getPodProgressStatusAtTimeOfFirstLoggedFaultEvent());
|
||||
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());
|
||||
assertEquals(LogEventErrorCode.NONE, podInfoFaultEvent.getLogEventErrorType());
|
||||
assertEquals(PodProgressStatus.PRIMING_COMPLETED, podInfoFaultEvent.getPodProgressStatusAtTimeOfFirstLoggedFaultEvent());
|
||||
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());
|
||||
assertEquals(LogEventErrorCode.NONE, podInfoFaultEvent.getLogEventErrorType());
|
||||
assertEquals(PodProgressStatus.ABOVE_FIFTY_UNITS, podInfoFaultEvent.getPodProgressStatusAtTimeOfFirstLoggedFaultEvent());
|
||||
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());
|
||||
assertEquals(LogEventErrorCode.INTERNAL_2_BIT_VARIABLE_SET_AND_MANIPULATED_IN_MAIN_LOOP_ROUTINES_2, podInfoFaultEvent.getLogEventErrorType());
|
||||
assertEquals(PodProgressStatus.ABOVE_FIFTY_UNITS, podInfoFaultEvent.getPodProgressStatusAtTimeOfFirstLoggedFaultEvent());
|
||||
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());
|
||||
assertEquals(LogEventErrorCode.INTERNAL_2_BIT_VARIABLE_SET_AND_MANIPULATED_IN_MAIN_LOOP_ROUTINES_2, podInfoFaultEvent.getLogEventErrorType());
|
||||
assertEquals(PodProgressStatus.ABOVE_FIFTY_UNITS, podInfoFaultEvent.getPodProgressStatusAtTimeOfFirstLoggedFaultEvent());
|
||||
assertEquals(2, podInfoFaultEvent.getReceiverLowGain());
|
||||
assertEquals(39, podInfoFaultEvent.getRadioRSSI());
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
@ -39,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(LogEventErrorCode.INTERNAL_2_BIT_VARIABLE_SET_AND_MANIPULATED_IN_MAIN_LOOP_ROUTINES_2, podInfo.getLogEventErrorType());
|
||||
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();
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
package info.nightscout.androidaps.plugins.pump.common.events
|
||||
|
||||
import info.nightscout.androidaps.events.Event
|
||||
import info.nightscout.androidaps.events.EventStatus
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpDeviceState
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
|
||||
open class EventRileyLinkDeviceStatusChange : Event {
|
||||
open class EventRileyLinkDeviceStatusChange : EventStatus {
|
||||
|
||||
var rileyLinkTargetDevice: RileyLinkTargetDevice? = null
|
||||
var rileyLinkServiceState: RileyLinkServiceState? = null
|
||||
var rileyLinkError: RileyLinkError? = null
|
||||
|
||||
|
@ -14,11 +17,10 @@ open class EventRileyLinkDeviceStatusChange : Event {
|
|||
var errorDescription: String? = null
|
||||
|
||||
constructor() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
constructor(rileyLinkServiceState: RileyLinkServiceState?, rileyLinkError: RileyLinkError?) {
|
||||
constructor(rileyLinkTargetDevice: RileyLinkTargetDevice, rileyLinkServiceState: RileyLinkServiceState?, rileyLinkError: RileyLinkError?) {
|
||||
this.rileyLinkTargetDevice = rileyLinkTargetDevice
|
||||
this.rileyLinkServiceState = rileyLinkServiceState
|
||||
this.rileyLinkError = rileyLinkError
|
||||
}
|
||||
|
@ -31,4 +33,17 @@ open class EventRileyLinkDeviceStatusChange : Event {
|
|||
this.pumpDeviceState = pumpDeviceState
|
||||
this.errorDescription = errorDescription
|
||||
}
|
||||
|
||||
override fun getStatus(resourceHelper: ResourceHelper): String {
|
||||
val rileyLinkServiceState = this.rileyLinkServiceState ?: return ""
|
||||
val resourceId = rileyLinkServiceState.resourceId
|
||||
val rileyLinkError = this.rileyLinkError
|
||||
|
||||
if (rileyLinkServiceState.isError && rileyLinkError != null) {
|
||||
val rileyLinkTargetDevice = this.rileyLinkTargetDevice ?: return ""
|
||||
return resourceHelper.gs(rileyLinkError.getResourceId(rileyLinkTargetDevice))
|
||||
}
|
||||
|
||||
return resourceHelper.gs(resourceId)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,8 +24,6 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.Rile
|
|||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.data.ServiceResult;
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.data.ServiceTransport;
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper;
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP;
|
||||
|
||||
|
@ -114,6 +112,10 @@ public abstract class RileyLinkService extends DaggerService {
|
|||
|
||||
public abstract RileyLinkCommunicationManager getDeviceCommunicationManager();
|
||||
|
||||
public RileyLinkServiceState getRileyLinkServiceState() {
|
||||
return rileyLinkServiceData == null ? null : rileyLinkServiceData.rileyLinkServiceState;
|
||||
}
|
||||
|
||||
// Here is where the wake-lock begins:
|
||||
// We've received a service startCommand, we grab the lock.
|
||||
@Override
|
||||
|
|
|
@ -33,8 +33,7 @@ public class RileyLinkServiceData {
|
|||
public RileyLinkServiceState rileyLinkServiceState = RileyLinkServiceState.NotStarted;
|
||||
private long lastServiceStateChange = 0L;
|
||||
public RileyLinkFirmwareVersion firmwareVersion;
|
||||
public RileyLinkTargetFrequency rileyLinkTargetFrequency; // TODO this might not be correct place
|
||||
|
||||
public RileyLinkTargetFrequency rileyLinkTargetFrequency;
|
||||
public String rileylinkAddress;
|
||||
long lastTuneUpTime = 0L;
|
||||
public Double lastGoodFrequency;
|
||||
|
@ -44,7 +43,7 @@ public class RileyLinkServiceData {
|
|||
// radio version
|
||||
public RileyLinkFirmwareVersion versionCC110;
|
||||
|
||||
public RileyLinkTargetDevice targetDevice; // TODO this might not be correct place
|
||||
public RileyLinkTargetDevice targetDevice;
|
||||
|
||||
// Medtronic Pump
|
||||
public String pumpID;
|
||||
|
@ -86,7 +85,7 @@ public class RileyLinkServiceData {
|
|||
aapsLogger.info(LTag.PUMP, "RileyLink State Changed: {} {}", newState, errorCode == null ? "" : " - Error State: " + errorCode.name());
|
||||
|
||||
rileyLinkUtil.getRileyLinkHistory().add(new RLHistoryItem(rileyLinkServiceState, errorCode, targetDevice));
|
||||
rxBus.send(new EventRileyLinkDeviceStatusChange(newState, errorCode));
|
||||
rxBus.send(new EventRileyLinkDeviceStatusChange(targetDevice, newState, errorCode));
|
||||
return null;
|
||||
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue