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
|
@ -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.local.LocalProfilePlugin
|
||||||
import info.nightscout.androidaps.plugins.profile.ns.NSProfileFragment
|
import info.nightscout.androidaps.plugins.profile.ns.NSProfileFragment
|
||||||
import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin
|
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.plugins.pump.omnipod.OmnipodPumpPlugin
|
||||||
import info.nightscout.androidaps.setupwizard.elements.*
|
import info.nightscout.androidaps.setupwizard.elements.*
|
||||||
import info.nightscout.androidaps.setupwizard.events.EventSWUpdate
|
import info.nightscout.androidaps.setupwizard.events.EventSWUpdate
|
||||||
|
@ -324,6 +325,12 @@ class SWDefinition @Inject constructor(
|
||||||
val activePump = activePlugin.activePump
|
val activePump = activePlugin.activePump
|
||||||
activePump is OmnipodPumpPlugin && !activePump.isRileyLinkReady
|
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)
|
.add(SWButton(injector)
|
||||||
.text(R.string.readstatus)
|
.text(R.string.readstatus)
|
||||||
.action(Runnable { commandQueue.readStatus("Clicked connect to pump", null) })
|
.action(Runnable { commandQueue.readStatus("Clicked connect to pump", null) })
|
||||||
|
@ -332,7 +339,8 @@ class SWDefinition @Inject constructor(
|
||||||
// Getting the status might not be possible
|
// Getting the status might not be possible
|
||||||
activePlugin.activePump !is OmnipodPumpPlugin
|
activePlugin.activePump !is OmnipodPumpPlugin
|
||||||
}))
|
}))
|
||||||
.add(SWEventListener(injector, EventPumpStatusChanged::class.java))
|
.add(SWEventListener(injector, EventPumpStatusChanged::class.java)
|
||||||
|
.visibility(SWValidator { activePlugin.activePump !is OmnipodPumpPlugin }))
|
||||||
.validator(SWValidator {
|
.validator(SWValidator {
|
||||||
isPumpInitialized()
|
isPumpInitialized()
|
||||||
})
|
})
|
||||||
|
|
|
@ -11,7 +11,7 @@ import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
|
|
||||||
class SWEventListener constructor(
|
class SWEventListener constructor(
|
||||||
injector:HasAndroidInjector,
|
injector: HasAndroidInjector,
|
||||||
clazz: Class<out EventStatus>
|
clazz: Class<out EventStatus>
|
||||||
) : SWItem(injector, Type.LISTENER) {
|
) : SWItem(injector, Type.LISTENER) {
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ class SWEventListener constructor(
|
||||||
private var textLabel = 0
|
private var textLabel = 0
|
||||||
private var status = ""
|
private var status = ""
|
||||||
private var textView: TextView? = null
|
private var textView: TextView? = null
|
||||||
|
private var visibilityValidator: SWValidator? = null
|
||||||
|
|
||||||
// TODO: Adrian how to clear disposable in this case?
|
// TODO: Adrian how to clear disposable in this case?
|
||||||
init {
|
init {
|
||||||
|
@ -43,6 +44,11 @@ class SWEventListener constructor(
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun visibility(visibilityValidator: SWValidator): SWEventListener {
|
||||||
|
this.visibilityValidator = visibilityValidator
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
override fun generateDialog(layout: LinearLayout) {
|
override fun generateDialog(layout: LinearLayout) {
|
||||||
val context = layout.context
|
val context = layout.context
|
||||||
|
@ -51,4 +57,8 @@ class SWEventListener constructor(
|
||||||
textView?.text = (if (textLabel != 0) resourceHelper.gs(textLabel) else "") + " " + status
|
textView?.text = (if (textLabel != 0) resourceHelper.gs(textLabel) else "") + " " + status
|
||||||
layout.addView(textView)
|
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="worker_state">Worker State: %s</string>
|
||||||
<string name="uploaded_data">Uploaded Data</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="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>
|
</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.definition.OmnipodStorageKeys;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.service.ExpirationReminderBuilder;
|
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.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.AlertConfiguration;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus;
|
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager;
|
import info.nightscout.androidaps.plugins.pump.omnipod.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
|
// When PodStateManager is created, which causes an IllegalArgumentException for DateTimeZones not being recognized
|
||||||
podStateManager.loadPodState();
|
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(
|
lastConnectionTimeMillis = sp.getLong(
|
||||||
RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L);
|
RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L);
|
||||||
|
|
||||||
|
@ -922,7 +930,7 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeAfterRileyLinkConnection() {
|
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++) {
|
for (int i = 0; STARTUP_STATUS_REQUEST_TRIES > i; i++) {
|
||||||
PumpEnactResult result = executeCommand(OmnipodCommandType.GET_POD_STATUS, aapsOmnipodManager::getPodStatus);
|
PumpEnactResult result = executeCommand(OmnipodCommandType.GET_POD_STATUS, aapsOmnipodManager::getPodStatus);
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
|
|
|
@ -5,40 +5,45 @@ import org.joda.time.DateTimeZone;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Random;
|
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.OmnipodMessage;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.AssignAddressCommand;
|
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.communication.message.response.VersionResponse;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants;
|
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.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.exception.IllegalVersionResponseTypeException;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager;
|
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager;
|
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 PodStateManager podStateManager;
|
||||||
|
private final AAPSLogger aapsLogger;
|
||||||
|
|
||||||
public AssignAddressAction(PodStateManager podStateManager) {
|
public AssignAddressAction(PodStateManager podStateManager, AAPSLogger aapsLogger) {
|
||||||
if (podStateManager == null) {
|
if (podStateManager == null) {
|
||||||
throw new IllegalArgumentException("podStateManager can not be null");
|
throw new IllegalArgumentException("podStateManager can not be null");
|
||||||
}
|
}
|
||||||
|
if (aapsLogger == null) {
|
||||||
|
throw new IllegalArgumentException("Logger can not be null");
|
||||||
|
}
|
||||||
this.podStateManager = podStateManager;
|
this.podStateManager = podStateManager;
|
||||||
|
this.aapsLogger = aapsLogger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VersionResponse execute(OmnipodRileyLinkCommunicationManager communicationService) {
|
public Void execute(OmnipodRileyLinkCommunicationManager communicationService) {
|
||||||
if (!podStateManager.hasPodState()) {
|
if (!podStateManager.hasPodState()) {
|
||||||
podStateManager.initState(generateRandomAddress());
|
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());
|
AssignAddressCommand assignAddress = new AssignAddressCommand(podStateManager.getAddress());
|
||||||
OmnipodMessage assignAddressMessage = new OmnipodMessage(OmnipodConstants.DEFAULT_ADDRESS,
|
OmnipodMessage assignAddressMessage = new OmnipodMessage(OmnipodConstants.DEFAULT_ADDRESS,
|
||||||
Collections.singletonList(assignAddress), podStateManager.getMessageNumber());
|
Collections.singletonList(assignAddress), podStateManager.getMessageNumber());
|
||||||
|
|
||||||
|
try {
|
||||||
VersionResponse assignAddressResponse = communicationService.exchangeMessages(VersionResponse.class, podStateManager, assignAddressMessage,
|
VersionResponse assignAddressResponse = communicationService.exchangeMessages(VersionResponse.class, podStateManager, assignAddressMessage,
|
||||||
OmnipodConstants.DEFAULT_ADDRESS, podStateManager.getAddress());
|
OmnipodConstants.DEFAULT_ADDRESS, podStateManager.getAddress());
|
||||||
|
|
||||||
|
@ -51,8 +56,17 @@ public class AssignAddressAction implements OmnipodAction<VersionResponse> {
|
||||||
|
|
||||||
podStateManager.setInitializationParameters(assignAddressResponse.getLot(), assignAddressResponse.getTid(), //
|
podStateManager.setInitializationParameters(assignAddressResponse.getLot(), assignAddressResponse.getTid(), //
|
||||||
assignAddressResponse.getPiVersion(), assignAddressResponse.getPmVersion(), DateTimeZone.getDefault(), assignAddressResponse.getPodProgressStatus());
|
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() {
|
private static int generateRandomAddress() {
|
||||||
|
|
|
@ -6,16 +6,15 @@ import java.util.List;
|
||||||
import java.util.Optional;
|
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.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.AlertConfiguration;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants;
|
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.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.driver.manager.PodStateManager;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager;
|
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 PodStateManager podStateManager;
|
||||||
private final BasalSchedule initialBasalSchedule;
|
private final BasalSchedule initialBasalSchedule;
|
||||||
|
@ -37,31 +36,33 @@ public class InsertCannulaAction implements OmnipodAction<StatusResponse> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StatusResponse execute(OmnipodRileyLinkCommunicationManager communicationService) {
|
public Void execute(OmnipodRileyLinkCommunicationManager communicationService) {
|
||||||
if (!podStateManager.isPodInitialized() || podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.PRIMING_COMPLETED)) {
|
if (podStateManager.getActivationProgress().isBefore(ActivationProgress.PRIMING_COMPLETED)) {
|
||||||
throw new IllegalPodProgressException(PodProgressStatus.PRIMING_COMPLETED, podStateManager.isPodInitialized() ? podStateManager.getPodProgressStatus() : null);
|
throw new IllegalActivationProgressException(ActivationProgress.PRIMING_COMPLETED, podStateManager.getActivationProgress());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.BASAL_INITIALIZED)) {
|
if (podStateManager.getActivationProgress().needsBasalSchedule()) {
|
||||||
podStateManager.setBasalSchedule(initialBasalSchedule);
|
podStateManager.setBasalSchedule(initialBasalSchedule);
|
||||||
communicationService.executeAction(new SetBasalScheduleAction(podStateManager, initialBasalSchedule,
|
communicationService.executeAction(new SetBasalScheduleAction(podStateManager, initialBasalSchedule,
|
||||||
true, podStateManager.getScheduleOffset(), false));
|
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()));
|
communicationService.executeAction(new ConfigureAlertsAction(podStateManager, buildAlertConfigurations()));
|
||||||
|
|
||||||
podStateManager.setExpirationAlertTimeBeforeShutdown(expirationReminderTimeBeforeShutdown);
|
podStateManager.setExpirationAlertTimeBeforeShutdown(expirationReminderTimeBeforeShutdown);
|
||||||
podStateManager.setLowReservoirAlertUnits(lowReservoirAlertUnits);
|
podStateManager.setLowReservoirAlertUnits(lowReservoirAlertUnits);
|
||||||
|
podStateManager.setActivationProgress(ActivationProgress.EXPIRATION_REMINDERS_SET);
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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() {
|
private List<AlertConfiguration> buildAlertConfigurations() {
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action;
|
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.action.service.PrimeService;
|
||||||
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.PodProgressStatus;
|
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalActivationProgressException;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager;
|
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager;
|
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 PrimeService service;
|
||||||
private final PodStateManager podStateManager;
|
private final PodStateManager podStateManager;
|
||||||
|
@ -24,21 +23,27 @@ public class PrimeAction implements OmnipodAction<StatusResponse> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StatusResponse execute(OmnipodRileyLinkCommunicationManager communicationService) {
|
public Void execute(OmnipodRileyLinkCommunicationManager communicationService) {
|
||||||
if (!podStateManager.isPodInitialized() || podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.PAIRING_COMPLETED)) {
|
if (podStateManager.getActivationProgress().isBefore(ActivationProgress.PAIRING_COMPLETED)) {
|
||||||
throw new IllegalPodProgressException(PodProgressStatus.PAIRING_COMPLETED, podStateManager.isPodInitialized() ? podStateManager.getPodProgressStatus() : null);
|
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
|
// FaultConfigCommand sets internal pod variables to effectively disable $6x faults which occur more often with a 0 TBR
|
||||||
service.executeDisableTab5Sub16And17FaultConfigCommand(communicationService, podStateManager);
|
service.executeDisableTab5Sub16And17FaultConfigCommand(communicationService, podStateManager);
|
||||||
|
podStateManager.setActivationProgress(ActivationProgress.TAB_5_SUB_16_AND_17_DISABLED);
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 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.OmnipodMessage;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.SetupPodCommand;
|
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.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.OmnipodConstants;
|
||||||
|
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PacketType;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus;
|
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalMessageAddressException;
|
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.IllegalPodProgressException;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalVersionResponseTypeException;
|
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.driver.manager.PodStateManager;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager;
|
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 PodStateManager podStateManager;
|
||||||
|
private final AAPSLogger aapsLogger;
|
||||||
|
|
||||||
public SetupPodAction(PodStateManager podStateManager) {
|
public SetupPodAction(PodStateManager podStateManager, AAPSLogger aapsLogger) {
|
||||||
if (podStateManager == null) {
|
if (podStateManager == null) {
|
||||||
throw new IllegalArgumentException("Pod state manager can not be 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.podStateManager = podStateManager;
|
||||||
|
this.aapsLogger = aapsLogger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VersionResponse execute(OmnipodRileyLinkCommunicationManager communicationService) {
|
public Void execute(OmnipodRileyLinkCommunicationManager communicationService) {
|
||||||
if (!podStateManager.isPodInitialized() || !podStateManager.getPodProgressStatus().equals(PodProgressStatus.REMINDER_INITIALIZED)) {
|
if (!podStateManager.isPodInitialized()) {
|
||||||
throw new IllegalPodProgressException(PodProgressStatus.REMINDER_INITIALIZED, podStateManager.isPodInitialized() ? podStateManager.getPodProgressStatus() : null);
|
throw new IllegalPodProgressException(PodProgressStatus.REMINDER_INITIALIZED, podStateManager.isPodInitialized() ? podStateManager.getPodProgressStatus() : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (podStateManager.getActivationProgress().needsPairing()) {
|
||||||
DateTime activationDate = DateTime.now(podStateManager.getTimeZone());
|
DateTime activationDate = DateTime.now(podStateManager.getTimeZone());
|
||||||
|
|
||||||
SetupPodCommand setupPodCommand = new SetupPodCommand(podStateManager.getAddress(), activationDate,
|
SetupPodCommand setupPodCommand = new SetupPodCommand(podStateManager.getAddress(), activationDate,
|
||||||
podStateManager.getLot(), podStateManager.getTid());
|
podStateManager.getLot(), podStateManager.getTid());
|
||||||
OmnipodMessage message = new OmnipodMessage(OmnipodConstants.DEFAULT_ADDRESS,
|
OmnipodMessage message = new OmnipodMessage(OmnipodConstants.DEFAULT_ADDRESS,
|
||||||
Collections.singletonList(setupPodCommand), podStateManager.getMessageNumber());
|
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());
|
message, OmnipodConstants.DEFAULT_ADDRESS, podStateManager.getAddress());
|
||||||
|
|
||||||
if (!setupPodResponse.isSetupPodVersionResponse()) {
|
if (!setupPodResponse.isSetupPodVersionResponse()) {
|
||||||
|
@ -46,7 +58,18 @@ public class SetupPodAction implements OmnipodAction<VersionResponse> {
|
||||||
if (setupPodResponse.getAddress() != podStateManager.getAddress()) {
|
if (setupPodResponse.getAddress() != podStateManager.getAddress()) {
|
||||||
throw new IllegalMessageAddressException(podStateManager.getAddress(), setupPodResponse.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 static final int MESSAGE_LENGTH = 5;
|
||||||
|
|
||||||
private final byte errorResponseCode;
|
private final byte errorResponseCode;
|
||||||
private Integer nonceSearchKey; // only valid for BAD_NONCE
|
|
||||||
private FaultEventCode faultEventCode; // valid for all but BAD_NONCE
|
private final Integer nonceSearchKey; // only valid for BAD_NONCE
|
||||||
private PodProgressStatus podProgressStatus; // valid for all but 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) {
|
public ErrorResponse(byte[] encodedData) {
|
||||||
if (encodedData.length < MESSAGE_LENGTH) {
|
if (encodedData.length < MESSAGE_LENGTH) {
|
||||||
|
@ -24,11 +26,16 @@ public class ErrorResponse extends MessageBlock {
|
||||||
|
|
||||||
errorResponseCode = encodedData[2];
|
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]);
|
nonceSearchKey = ByteUtil.makeUnsignedShort(encodedData[3], encodedData[4]);
|
||||||
|
|
||||||
|
faultEventCode = null;
|
||||||
|
podProgressStatus = null;
|
||||||
} else {
|
} else {
|
||||||
faultEventCode = FaultEventCode.fromByte(encodedData[3]);
|
faultEventCode = FaultEventCode.fromByte(encodedData[3]);
|
||||||
podProgressStatus = PodProgressStatus.fromByte(encodedData[4]);
|
podProgressStatus = PodProgressStatus.fromByte(encodedData[4]);
|
||||||
|
|
||||||
|
nonceSearchKey = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,8 +60,7 @@ public class ErrorResponse extends MessageBlock {
|
||||||
return nonceSearchKey;
|
return nonceSearchKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override public String toString() {
|
||||||
public String toString() {
|
|
||||||
return "ErrorResponse{" +
|
return "ErrorResponse{" +
|
||||||
"errorResponseCode=" + errorResponseCode +
|
"errorResponseCode=" + errorResponseCode +
|
||||||
", nonceSearchKey=" + nonceSearchKey +
|
", nonceSearchKey=" + nonceSearchKey +
|
||||||
|
|
|
@ -3,7 +3,6 @@ package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.mes
|
||||||
import org.joda.time.Duration;
|
import org.joda.time.Duration;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
|
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
|
||||||
|
@ -54,7 +53,7 @@ public class PodInfoActiveAlerts extends PodInfo {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "PodInfoActiveAlerts{" +
|
return "PodInfoActiveAlerts{" +
|
||||||
"word278=" + Arrays.toString(word278) +
|
"word278=" + ByteUtil.shortHexString(word278) +
|
||||||
", alertActivations=" + alertActivations +
|
", 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.communication.message.response.StatusUpdatableResponse;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertSet;
|
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.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.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.OmnipodConstants;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType;
|
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.PodProgressStatus;
|
||||||
|
|
||||||
public class PodInfoFaultEvent extends PodInfo implements StatusUpdatableResponse {
|
public class PodInfoDetailedStatus extends PodInfo implements StatusUpdatableResponse {
|
||||||
private static final int MINIMUM_MESSAGE_LENGTH = 21;
|
private static final int MINIMUM_MESSAGE_LENGTH = 21;
|
||||||
|
|
||||||
private final PodProgressStatus podProgressStatus;
|
private final PodProgressStatus podProgressStatus;
|
||||||
|
@ -27,14 +27,13 @@ public class PodInfoFaultEvent extends PodInfo implements StatusUpdatableRespons
|
||||||
private final Duration timeActive;
|
private final Duration timeActive;
|
||||||
private final AlertSet unacknowledgedAlerts;
|
private final AlertSet unacknowledgedAlerts;
|
||||||
private final boolean faultAccessingTables;
|
private final boolean faultAccessingTables;
|
||||||
private final LogEventErrorCode logEventErrorType;
|
private final ErrorEventInfo errorEventInfo;
|
||||||
private final PodProgressStatus logEventErrorPodProgressStatus;
|
|
||||||
private final byte receiverLowGain;
|
private final byte receiverLowGain;
|
||||||
private final byte radioRSSI;
|
private final byte radioRSSI;
|
||||||
private final PodProgressStatus podProgressStatusAtTimeOfFirstLoggedFaultEvent;
|
private final PodProgressStatus previousPodProgressStatus;
|
||||||
private final byte[] unknownValue;
|
private final byte[] unknownValue;
|
||||||
|
|
||||||
public PodInfoFaultEvent(byte[] encodedData) {
|
public PodInfoDetailedStatus(byte[] encodedData) {
|
||||||
super(encodedData);
|
super(encodedData);
|
||||||
|
|
||||||
if (encodedData.length < MINIMUM_MESSAGE_LENGTH) {
|
if (encodedData.length < MINIMUM_MESSAGE_LENGTH) {
|
||||||
|
@ -69,27 +68,33 @@ public class PodInfoFaultEvent extends PodInfo implements StatusUpdatableRespons
|
||||||
|
|
||||||
unacknowledgedAlerts = new AlertSet(encodedData[15]);
|
unacknowledgedAlerts = new AlertSet(encodedData[15]);
|
||||||
faultAccessingTables = encodedData[16] == 0x02;
|
faultAccessingTables = encodedData[16] == 0x02;
|
||||||
int i = ByteUtil.convertUnsignedByteToInt(encodedData[17]);
|
byte rawErrorEventInfo = encodedData[17];
|
||||||
byte value = (byte) (i >>> 4);
|
if (rawErrorEventInfo == 0x00) {
|
||||||
|
errorEventInfo = null;
|
||||||
// FIXME below line DOES NOT MATCH the OpenOmni Wiki description of the type 2 pod info response
|
} else {
|
||||||
// See https://github.com/openaps/openomni/wiki/Command-02-Pod-Information-Response#type-2
|
errorEventInfo = ErrorEventInfo.fromByte(rawErrorEventInfo);
|
||||||
// Example of an observed message from the Pod that makes below line throw an IllegalArgumentException:
|
}
|
||||||
// 1F0F038F20180216020D00000000000012FFFF03FF00160000879A070000012E
|
|
||||||
// the LogEventErrorCode class doesn't make any sense and should be removed. Instead, the a, bb and c bits in byte 17
|
|
||||||
// should be decoded independently as per the response description on the OpenOmni Wiki
|
|
||||||
logEventErrorType = LogEventErrorCode.fromByte(value);
|
|
||||||
|
|
||||||
logEventErrorPodProgressStatus = PodProgressStatus.fromByte((byte) (encodedData[17] & 0x0f));
|
|
||||||
receiverLowGain = (byte) (ByteUtil.convertUnsignedByteToInt(encodedData[18]) >>> 6);
|
receiverLowGain = (byte) (ByteUtil.convertUnsignedByteToInt(encodedData[18]) >>> 6);
|
||||||
radioRSSI = (byte) (encodedData[18] & 0x3f);
|
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);
|
unknownValue = ByteUtil.substring(encodedData, 20, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PodInfoType getType() {
|
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() {
|
@Override public PodProgressStatus getPodProgressStatus() {
|
||||||
|
@ -140,12 +145,8 @@ public class PodInfoFaultEvent extends PodInfo implements StatusUpdatableRespons
|
||||||
return faultAccessingTables;
|
return faultAccessingTables;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LogEventErrorCode getLogEventErrorType() {
|
public ErrorEventInfo getErrorEventInfo() {
|
||||||
return logEventErrorType;
|
return errorEventInfo;
|
||||||
}
|
|
||||||
|
|
||||||
public PodProgressStatus getLogEventErrorPodProgressStatus() {
|
|
||||||
return logEventErrorPodProgressStatus;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte getReceiverLowGain() {
|
public byte getReceiverLowGain() {
|
||||||
|
@ -156,8 +157,8 @@ public class PodInfoFaultEvent extends PodInfo implements StatusUpdatableRespons
|
||||||
return radioRSSI;
|
return radioRSSI;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PodProgressStatus getPodProgressStatusAtTimeOfFirstLoggedFaultEvent() {
|
public PodProgressStatus getPreviousPodProgressStatus() {
|
||||||
return podProgressStatusAtTimeOfFirstLoggedFaultEvent;
|
return previousPodProgressStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getUnknownValue() {
|
public byte[] getUnknownValue() {
|
||||||
|
@ -165,7 +166,7 @@ public class PodInfoFaultEvent extends PodInfo implements StatusUpdatableRespons
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public String toString() {
|
@Override public String toString() {
|
||||||
return "PodInfoFaultEvent{" +
|
return "PodInfoDetailedStatus{" +
|
||||||
"podProgressStatus=" + podProgressStatus +
|
"podProgressStatus=" + podProgressStatus +
|
||||||
", deliveryStatus=" + deliveryStatus +
|
", deliveryStatus=" + deliveryStatus +
|
||||||
", bolusNotDelivered=" + bolusNotDelivered +
|
", bolusNotDelivered=" + bolusNotDelivered +
|
||||||
|
@ -178,11 +179,10 @@ public class PodInfoFaultEvent extends PodInfo implements StatusUpdatableRespons
|
||||||
", timeActive=" + timeActive +
|
", timeActive=" + timeActive +
|
||||||
", unacknowledgedAlerts=" + unacknowledgedAlerts +
|
", unacknowledgedAlerts=" + unacknowledgedAlerts +
|
||||||
", faultAccessingTables=" + faultAccessingTables +
|
", faultAccessingTables=" + faultAccessingTables +
|
||||||
", logEventErrorType=" + logEventErrorType +
|
", errorEventInfo=" + errorEventInfo +
|
||||||
", logEventErrorPodProgressStatus=" + logEventErrorPodProgressStatus +
|
|
||||||
", receiverLowGain=" + receiverLowGain +
|
", receiverLowGain=" + receiverLowGain +
|
||||||
", radioRSSI=" + radioRSSI +
|
", radioRSSI=" + radioRSSI +
|
||||||
", podProgressStatusAtTimeOfFirstLoggedFaultEvent=" + podProgressStatusAtTimeOfFirstLoggedFaultEvent +
|
", previousPodProgressStatus=" + previousPodProgressStatus +
|
||||||
", unknownValue=" + ByteUtil.shortHexString(unknownValue) +
|
", 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;
|
import java.util.Locale;
|
||||||
|
|
||||||
public enum FaultEventCode {
|
public enum FaultEventCode {
|
||||||
NO_FAULTS((byte) 0x00),
|
|
||||||
FAILED_FLASH_ERASE((byte) 0x01),
|
FAILED_FLASH_ERASE((byte) 0x01),
|
||||||
FAILED_FLASH_STORE((byte) 0x02),
|
FAILED_FLASH_STORE((byte) 0x02),
|
||||||
TABLE_CORRUPTION_BASAL_SUBCOMMAND((byte) 0x03),
|
TABLE_CORRUPTION_BASAL_SUBCOMMAND((byte) 0x03),
|
||||||
|
@ -129,6 +128,9 @@ public enum FaultEventCode {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FaultEventCode fromByte(byte value) {
|
public static FaultEventCode fromByte(byte value) {
|
||||||
|
if (value == 0x00) { // No faults
|
||||||
|
return null;
|
||||||
|
}
|
||||||
for (FaultEventCode type : values()) {
|
for (FaultEventCode type : values()) {
|
||||||
if (type.value == value) {
|
if (type.value == value) {
|
||||||
return type;
|
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.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.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.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.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.PodInfoOlderPulseLog;
|
||||||
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.PodInfoRecentPulseLog;
|
||||||
|
|
||||||
public enum PodInfoType {
|
public enum PodInfoType {
|
||||||
NORMAL((byte) 0x00),
|
NORMAL((byte) 0x00),
|
||||||
ACTIVE_ALERTS((byte) 0x01),
|
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.
|
DATA_LOG((byte) 0x03), // Similar to types $50 & $51. Returns up to the last 60 dwords of data.
|
||||||
FAULT_AND_INITIALIZATION_TIME((byte) 0x05),
|
FAULT_AND_INITIALIZATION_TIME((byte) 0x05),
|
||||||
RECENT_PULSE_LOG((byte) 0x50), // Starting at $4200
|
RECENT_PULSE_LOG((byte) 0x50), // Starting at $4200
|
||||||
|
@ -44,8 +44,8 @@ public enum PodInfoType {
|
||||||
throw new UnsupportedOperationException("Cannot decode PodInfoType.NORMAL");
|
throw new UnsupportedOperationException("Cannot decode PodInfoType.NORMAL");
|
||||||
case ACTIVE_ALERTS:
|
case ACTIVE_ALERTS:
|
||||||
return new PodInfoActiveAlerts(encodedData);
|
return new PodInfoActiveAlerts(encodedData);
|
||||||
case FAULT_EVENT:
|
case DETAILED_STATUS:
|
||||||
return new PodInfoFaultEvent(encodedData);
|
return new PodInfoDetailedStatus(encodedData);
|
||||||
case DATA_LOG:
|
case DATA_LOG:
|
||||||
return new PodInfoDataLog(encodedData, bodyLength);
|
return new PodInfoDataLog(encodedData, bodyLength);
|
||||||
case FAULT_AND_INITIALIZATION_TIME:
|
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;
|
private final PodProgressStatus actual;
|
||||||
|
|
||||||
public IllegalPodProgressException(PodProgressStatus expected, 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.expected = expected;
|
||||||
this.actual = actual;
|
this.actual = actual;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception;
|
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 {
|
public class PodFaultException extends OmnipodException {
|
||||||
private final PodInfoFaultEvent faultEvent;
|
private final PodInfoDetailedStatus detailedStatus;
|
||||||
|
|
||||||
public PodFaultException(PodInfoFaultEvent faultEvent) {
|
public PodFaultException(PodInfoDetailedStatus detailedStatus) {
|
||||||
super(faultEvent.getFaultEventCode().toString(), true);
|
super(detailedStatus.getFaultEventCode().toString(), true);
|
||||||
this.faultEvent = faultEvent;
|
this.detailedStatus = detailedStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PodInfoFaultEvent getFaultEvent() {
|
public PodInfoDetailedStatus getDetailedStatus() {
|
||||||
return faultEvent;
|
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.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.PodInfoRecentPulseLog;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoResponse;
|
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.AlertConfiguration;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.BeepType;
|
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.DeliveryStatus;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryType;
|
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.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.PodInfoType;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus;
|
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.BasalSchedule;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.CommandFailedAfterChangingDeliveryStatusException;
|
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.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.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.IllegalPodProgressException;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.NonceOutOfSyncException;
|
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.NonceOutOfSyncException;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.OmnipodException;
|
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.OmnipodException;
|
||||||
|
@ -59,7 +59,7 @@ import io.reactivex.schedulers.Schedulers;
|
||||||
import io.reactivex.subjects.SingleSubject;
|
import io.reactivex.subjects.SingleSubject;
|
||||||
|
|
||||||
public class OmnipodManager {
|
public class OmnipodManager {
|
||||||
private static final int ACTION_VERIFICATION_TRIES = 2;
|
private static final int ACTION_VERIFICATION_TRIES = 1;
|
||||||
|
|
||||||
private final OmnipodRileyLinkCommunicationManager communicationService;
|
private final OmnipodRileyLinkCommunicationManager communicationService;
|
||||||
private PodStateManager podStateManager;
|
private PodStateManager podStateManager;
|
||||||
|
@ -88,76 +88,53 @@ public class OmnipodManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized Single<Boolean> pairAndPrime() {
|
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
|
// Always send both 0x07 and 0x03 on retries
|
||||||
try {
|
if (podStateManager.getActivationProgress().isBefore(ActivationProgress.PAIRING_COMPLETED)) {
|
||||||
communicationService.executeAction(
|
communicationService.executeAction(
|
||||||
new AssignAddressAction(podStateManager));
|
new AssignAddressAction(podStateManager, aapsLogger));
|
||||||
} catch (IllegalPacketTypeException ex) {
|
|
||||||
if (ex.getActual() == PacketType.ACK && podStateManager.isPodInitialized()) {
|
|
||||||
// When we already assigned the address before, it's possible to only get an ACK here
|
|
||||||
aapsLogger.debug("Received ACK instead of response in AssignAddressAction. Ignoring because we already assigned the address successfully");
|
|
||||||
} else {
|
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
communicationService.executeAction(new SetupPodAction(podStateManager, aapsLogger));
|
||||||
communicationService.executeAction(new SetupPodAction(podStateManager));
|
|
||||||
} catch (IllegalPacketTypeException ex) {
|
|
||||||
if (PacketType.ACK.equals(ex.getActual())) {
|
|
||||||
// TODO is this true for the SetupPodCommand?
|
|
||||||
// Pod is already configured
|
|
||||||
aapsLogger.debug("Received ACK instead of response in SetupPodAction. Ignoring");
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else if (podStateManager.getPodProgressStatus().isAfter(PodProgressStatus.PRIMING)) {
|
|
||||||
throw new IllegalPodProgressException(PodProgressStatus.PAIRING_COMPLETED, podStateManager.getPodProgressStatus());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure we have an up to date PodProgressStatus
|
|
||||||
getPodStatus();
|
|
||||||
|
|
||||||
communicationService.executeAction(new PrimeAction(new PrimeService(), podStateManager));
|
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();
|
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) //
|
return Single.timer(delayInMillis, TimeUnit.MILLISECONDS) //
|
||||||
.map(o -> verifyPodProgressStatus(PodProgressStatus.PRIMING_COMPLETED)) //
|
.map(o -> verifyPodProgressStatus(PodProgressStatus.PRIMING_COMPLETED, ActivationProgress.PRIMING_COMPLETED)) //
|
||||||
.subscribeOn(Schedulers.io());
|
.subscribeOn(Schedulers.io());
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized Single<Boolean> insertCannula(
|
public synchronized Single<Boolean> insertCannula(
|
||||||
BasalSchedule basalSchedule, Duration expirationReminderTimeBeforeShutdown, Integer lowReservoirAlertUnits) {
|
BasalSchedule basalSchedule, Duration expirationReminderTimeBeforeShutdown, Integer lowReservoirAlertUnits) {
|
||||||
if (!podStateManager.isPodInitialized() || podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.PRIMING_COMPLETED)) {
|
if (podStateManager.getActivationProgress().isBefore(ActivationProgress.PRIMING_COMPLETED)) {
|
||||||
throw new IllegalPodProgressException(PodProgressStatus.PRIMING_COMPLETED, !podStateManager.isPodInitialized() ? null : podStateManager.getPodProgressStatus());
|
throw new IllegalActivationProgressException(ActivationProgress.PRIMING_COMPLETED, podStateManager.getActivationProgress());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure we have the latest PodProgressStatus
|
if (podStateManager.isPodInitialized()) {
|
||||||
getPodStatus();
|
if (podStateManager.getActivationProgress().isCompleted()) {
|
||||||
|
return Single.just(true);
|
||||||
if (podStateManager.getPodProgressStatus().isAfter(PodProgressStatus.INSERTING_CANNULA)) {
|
}
|
||||||
throw new IllegalPodProgressException(PodProgressStatus.PRIMING_COMPLETED, podStateManager.getPodProgressStatus());
|
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));
|
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();
|
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) //
|
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());
|
.subscribeOn(Schedulers.io());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,49 +143,29 @@ public class OmnipodManager {
|
||||||
throw new IllegalPodProgressException(PodProgressStatus.REMINDER_INITIALIZED, null);
|
throw new IllegalPodProgressException(PodProgressStatus.REMINDER_INITIALIZED, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
logStartingCommandExecution("getPodStatus");
|
|
||||||
|
|
||||||
try {
|
|
||||||
return communicationService.executeAction(new GetStatusAction(podStateManager));
|
return communicationService.executeAction(new GetStatusAction(podStateManager));
|
||||||
} finally {
|
|
||||||
logCommandExecutionFinished("getPodStatus");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized PodInfoResponse getPodInfo(PodInfoType podInfoType) {
|
public synchronized PodInfoResponse getPodInfo(PodInfoType podInfoType) {
|
||||||
assertReadyForDelivery();
|
assertReadyForDelivery();
|
||||||
|
|
||||||
logStartingCommandExecution("getPodInfo");
|
|
||||||
|
|
||||||
try {
|
|
||||||
return communicationService.executeAction(new GetPodInfoAction(podStateManager, podInfoType));
|
return communicationService.executeAction(new GetPodInfoAction(podStateManager, podInfoType));
|
||||||
} finally {
|
|
||||||
logCommandExecutionFinished("getPodInfo");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized StatusResponse configureAlerts(List<AlertConfiguration> alertConfigurations) {
|
public synchronized StatusResponse configureAlerts(List<AlertConfiguration> alertConfigurations) {
|
||||||
assertReadyForDelivery();
|
assertReadyForDelivery();
|
||||||
logStartingCommandExecution("configureAlerts");
|
|
||||||
try {
|
|
||||||
StatusResponse statusResponse = executeAndVerify(() -> communicationService.executeAction(new ConfigureAlertsAction(podStateManager, alertConfigurations)));
|
StatusResponse statusResponse = executeAndVerify(() -> communicationService.executeAction(new ConfigureAlertsAction(podStateManager, alertConfigurations)));
|
||||||
ConfigureAlertsAction.updateConfiguredAlerts(podStateManager, alertConfigurations);
|
ConfigureAlertsAction.updateConfiguredAlerts(podStateManager, alertConfigurations);
|
||||||
return statusResponse;
|
return statusResponse;
|
||||||
} finally {
|
|
||||||
logCommandExecutionFinished("configureAlerts");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized StatusResponse acknowledgeAlerts() {
|
public synchronized StatusResponse acknowledgeAlerts() {
|
||||||
assertReadyForDelivery();
|
assertReadyForDelivery();
|
||||||
|
|
||||||
logStartingCommandExecution("acknowledgeAlerts");
|
|
||||||
|
|
||||||
try {
|
|
||||||
return executeAndVerify(() -> communicationService.executeAction(new AcknowledgeAlertsAction(podStateManager, podStateManager.getActiveAlerts())));
|
return executeAndVerify(() -> communicationService.executeAction(new AcknowledgeAlertsAction(podStateManager, podStateManager.getActiveAlerts())));
|
||||||
} finally {
|
|
||||||
logCommandExecutionFinished("acknowledgeAlerts");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CAUTION: cancels all delivery
|
// CAUTION: cancels all delivery
|
||||||
|
@ -216,9 +173,6 @@ public class OmnipodManager {
|
||||||
public synchronized void setBasalSchedule(BasalSchedule schedule, boolean acknowledgementBeep) {
|
public synchronized void setBasalSchedule(BasalSchedule schedule, boolean acknowledgementBeep) {
|
||||||
assertReadyForDelivery();
|
assertReadyForDelivery();
|
||||||
|
|
||||||
logStartingCommandExecution("setBasalSchedule [basalSchedule=" + schedule + ", acknowledgementBeep=" + acknowledgementBeep + "]");
|
|
||||||
|
|
||||||
try {
|
|
||||||
boolean wasSuspended = podStateManager.isSuspended();
|
boolean wasSuspended = podStateManager.isSuspended();
|
||||||
if (!wasSuspended) {
|
if (!wasSuspended) {
|
||||||
suspendDelivery(acknowledgementBeep);
|
suspendDelivery(acknowledgementBeep);
|
||||||
|
@ -247,22 +201,14 @@ public class OmnipodManager {
|
||||||
throw ex;
|
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
|
// 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) {
|
public synchronized void setTemporaryBasal(double rate, Duration duration, boolean acknowledgementBeep, boolean completionBeep) {
|
||||||
assertReadyForDelivery();
|
assertReadyForDelivery();
|
||||||
|
|
||||||
logStartingCommandExecution("setTemporaryBasal [rate=" + rate + ", duration=" + duration + ", acknowledgementBeep=" + acknowledgementBeep + ", completionBeep=" + completionBeep + "]");
|
|
||||||
|
|
||||||
boolean cancelCurrentTbr = podStateManager.isTempBasalRunning();
|
boolean cancelCurrentTbr = podStateManager.isTempBasalRunning();
|
||||||
|
|
||||||
try {
|
|
||||||
if (cancelCurrentTbr) {
|
if (cancelCurrentTbr) {
|
||||||
try {
|
try {
|
||||||
cancelDelivery(EnumSet.of(DeliveryType.TEMP_BASAL), acknowledgementBeep);
|
cancelDelivery(EnumSet.of(DeliveryType.TEMP_BASAL), acknowledgementBeep);
|
||||||
|
@ -320,9 +266,6 @@ public class OmnipodManager {
|
||||||
throw ex2;
|
throw ex2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
logCommandExecutionFinished("setTemporaryBasal");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void cancelTemporaryBasal(boolean acknowledgementBeep) {
|
public synchronized void cancelTemporaryBasal(boolean acknowledgementBeep) {
|
||||||
|
@ -348,17 +291,11 @@ public class OmnipodManager {
|
||||||
private synchronized StatusResponse cancelDelivery(EnumSet<DeliveryType> deliveryTypes, boolean acknowledgementBeep) {
|
private synchronized StatusResponse cancelDelivery(EnumSet<DeliveryType> deliveryTypes, boolean acknowledgementBeep) {
|
||||||
assertReadyForDelivery();
|
assertReadyForDelivery();
|
||||||
|
|
||||||
logStartingCommandExecution("cancelDelivery [deliveryTypes=" + deliveryTypes + ", acknowledgementBeep=" + acknowledgementBeep + "]");
|
|
||||||
|
|
||||||
try {
|
|
||||||
return executeAndVerify(() -> {
|
return executeAndVerify(() -> {
|
||||||
StatusResponse statusResponse = communicationService.executeAction(new CancelDeliveryAction(podStateManager, deliveryTypes, acknowledgementBeep));
|
StatusResponse statusResponse = communicationService.executeAction(new CancelDeliveryAction(podStateManager, deliveryTypes, acknowledgementBeep));
|
||||||
aapsLogger.info(LTag.PUMPCOMM, "Status response after cancel delivery[types={}]: {}", deliveryTypes.toString(), statusResponse.toString());
|
aapsLogger.info(LTag.PUMPCOMM, "Status response after cancel delivery[types={}]: {}", deliveryTypes.toString(), statusResponse.toString());
|
||||||
return statusResponse;
|
return statusResponse;
|
||||||
});
|
});
|
||||||
} finally {
|
|
||||||
logCommandExecutionFinished("cancelDelivery");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a SingleSubject that returns when the bolus has finished.
|
// 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) {
|
public synchronized BolusCommandResult bolus(Double units, boolean acknowledgementBeep, boolean completionBeep, BiConsumer<Double, Integer> progressIndicationConsumer) {
|
||||||
assertReadyForDelivery();
|
assertReadyForDelivery();
|
||||||
|
|
||||||
logStartingCommandExecution("bolus [units=" + units + ", acknowledgementBeep=" + acknowledgementBeep + ", completionBeep=" + completionBeep + "]");
|
|
||||||
|
|
||||||
bolusCommandExecutionSubject = SingleSubject.create();
|
bolusCommandExecutionSubject = SingleSubject.create();
|
||||||
|
|
||||||
CommandDeliveryStatus commandDeliveryStatus = CommandDeliveryStatus.SUCCESS;
|
CommandDeliveryStatus commandDeliveryStatus = CommandDeliveryStatus.SUCCESS;
|
||||||
|
@ -437,7 +372,7 @@ public class OmnipodManager {
|
||||||
break;
|
break;
|
||||||
} catch (PodFaultException ex) {
|
} catch (PodFaultException ex) {
|
||||||
// Subtract units not delivered in case of a Pod failure
|
// 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);
|
aapsLogger.debug(LTag.PUMPCOMM, "Caught PodFaultException in bolus completion verification", ex);
|
||||||
break;
|
break;
|
||||||
|
@ -454,8 +389,6 @@ public class OmnipodManager {
|
||||||
})
|
})
|
||||||
.subscribe());
|
.subscribe());
|
||||||
|
|
||||||
logCommandExecutionFinished("bolus");
|
|
||||||
|
|
||||||
return new BolusCommandResult(commandDeliveryStatus, bolusCompletionSubject);
|
return new BolusCommandResult(commandDeliveryStatus, bolusCompletionSubject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,16 +400,12 @@ public class OmnipodManager {
|
||||||
throw new IllegalDeliveryStatusException(DeliveryStatus.BOLUS_IN_PROGRESS, podStateManager.getLastDeliveryStatus());
|
throw new IllegalDeliveryStatusException(DeliveryStatus.BOLUS_IN_PROGRESS, podStateManager.getLastDeliveryStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
logStartingCommandExecution("cancelBolus [acknowledgementBeep=" + acknowledgementBeep + "]");
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
StatusResponse statusResponse = cancelDelivery(EnumSet.of(DeliveryType.BOLUS), acknowledgementBeep);
|
StatusResponse statusResponse = cancelDelivery(EnumSet.of(DeliveryType.BOLUS), acknowledgementBeep);
|
||||||
discardActiveBolusData(statusResponse.getBolusNotDelivered());
|
discardActiveBolusData(statusResponse.getBolusNotDelivered());
|
||||||
} catch (PodFaultException ex) {
|
} catch (PodFaultException ex) {
|
||||||
discardActiveBolusData(ex.getFaultEvent().getBolusNotDelivered());
|
discardActiveBolusData(ex.getDetailedStatus().getBolusNotDelivered());
|
||||||
throw ex;
|
throw ex;
|
||||||
} finally {
|
|
||||||
logCommandExecutionFinished("cancelBolus");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -494,7 +423,6 @@ public class OmnipodManager {
|
||||||
public synchronized void suspendDelivery(boolean acknowledgementBeep) {
|
public synchronized void suspendDelivery(boolean acknowledgementBeep) {
|
||||||
assertReadyForDelivery();
|
assertReadyForDelivery();
|
||||||
|
|
||||||
logStartingCommandExecution("suspendDelivery");
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
cancelDelivery(EnumSet.allOf(DeliveryType.class), acknowledgementBeep);
|
cancelDelivery(EnumSet.allOf(DeliveryType.class), acknowledgementBeep);
|
||||||
|
@ -508,8 +436,6 @@ public class OmnipodManager {
|
||||||
ex.setCertainFailure(true);
|
ex.setCertainFailure(true);
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
logCommandExecutionFinished("suspendDelivery");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,9 +444,6 @@ public class OmnipodManager {
|
||||||
public synchronized void setTime(boolean acknowledgementBeeps) {
|
public synchronized void setTime(boolean acknowledgementBeeps) {
|
||||||
assertReadyForDelivery();
|
assertReadyForDelivery();
|
||||||
|
|
||||||
logStartingCommandExecution("setTime [acknowledgementBeeps=" + acknowledgementBeeps + "]");
|
|
||||||
|
|
||||||
try {
|
|
||||||
DateTimeZone oldTimeZone = podStateManager.getTimeZone();
|
DateTimeZone oldTimeZone = podStateManager.getTimeZone();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -535,9 +458,6 @@ public class OmnipodManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
podStateManager.updateActivatedAt();
|
podStateManager.updateActivatedAt();
|
||||||
} finally {
|
|
||||||
logCommandExecutionFinished("setTime");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void deactivatePod() {
|
public synchronized void deactivatePod() {
|
||||||
|
@ -545,8 +465,6 @@ public class OmnipodManager {
|
||||||
throw new IllegalPodProgressException(PodProgressStatus.REMINDER_INITIALIZED, null);
|
throw new IllegalPodProgressException(PodProgressStatus.REMINDER_INITIALIZED, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
logStartingCommandExecution("deactivatePod");
|
|
||||||
|
|
||||||
// Try to get pulse log for diagnostics
|
// Try to get pulse log for diagnostics
|
||||||
try {
|
try {
|
||||||
PodInfoResponse podInfoResponse = communicationService.executeAction(new GetPodInfoAction(podStateManager, PodInfoType.RECENT_PULSE_LOG));
|
PodInfoResponse podInfoResponse = communicationService.executeAction(new GetPodInfoAction(podStateManager, PodInfoType.RECENT_PULSE_LOG));
|
||||||
|
@ -561,8 +479,6 @@ public class OmnipodManager {
|
||||||
communicationService.executeAction(new DeactivatePodAction(podStateManager, true));
|
communicationService.executeAction(new DeactivatePodAction(podStateManager, true));
|
||||||
} catch (PodFaultException ex) {
|
} catch (PodFaultException ex) {
|
||||||
aapsLogger.info(LTag.PUMPCOMM, "Ignoring PodFaultException in deactivatePod", ex);
|
aapsLogger.info(LTag.PUMPCOMM, "Ignoring PodFaultException in deactivatePod", ex);
|
||||||
} finally {
|
|
||||||
logCommandExecutionFinished("deactivatePod");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
podStateManager.discardState();
|
podStateManager.discardState();
|
||||||
|
@ -592,7 +508,6 @@ public class OmnipodManager {
|
||||||
|
|
||||||
// Only works for commands with nonce resyncable message blocks
|
// Only works for commands with nonce resyncable message blocks
|
||||||
private StatusResponse executeAndVerify(Supplier<StatusResponse> supplier) {
|
private StatusResponse executeAndVerify(Supplier<StatusResponse> supplier) {
|
||||||
logStartingCommandExecution("verifyCommand");
|
|
||||||
try {
|
try {
|
||||||
return supplier.get();
|
return supplier.get();
|
||||||
} catch (OmnipodException originalException) {
|
} catch (OmnipodException originalException) {
|
||||||
|
@ -616,8 +531,6 @@ public class OmnipodManager {
|
||||||
throw originalException;
|
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
|
* @return true if the Pod's progress status matches the expected status, otherwise false
|
||||||
* @throws PodProgressStatusVerificationFailedException in case reading the Pod status fails
|
* @throws PodProgressStatusVerificationFailedException in case reading the Pod status fails
|
||||||
*/
|
*/
|
||||||
private boolean verifyPodProgressStatus(PodProgressStatus expectedPodProgressStatus) {
|
private boolean verifyPodProgressStatus(PodProgressStatus expectedPodProgressStatus, ActivationProgress activationProgress) {
|
||||||
Boolean result = null;
|
Boolean result = null;
|
||||||
Throwable lastException = null;
|
Throwable lastException = null;
|
||||||
|
|
||||||
|
@ -641,6 +554,7 @@ public class OmnipodManager {
|
||||||
StatusResponse statusResponse = getPodStatus();
|
StatusResponse statusResponse = getPodStatus();
|
||||||
|
|
||||||
if (statusResponse.getPodProgressStatus().equals(expectedPodProgressStatus)) {
|
if (statusResponse.getPodProgressStatus().equals(expectedPodProgressStatus)) {
|
||||||
|
podStateManager.setActivationProgress(activationProgress);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
result = false;
|
result = false;
|
||||||
|
@ -681,14 +595,6 @@ public class OmnipodManager {
|
||||||
throw new DeliveryStatusVerificationFailedException(expectedStatus, verificationCause);
|
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) {
|
private Duration calculateEstimatedBolusDuration(DateTime startTime, double units, double deliveryRateInUnitsPerSecond) {
|
||||||
if (!podStateManager.isPodActivationCompleted()) {
|
if (!podStateManager.isPodActivationCompleted()) {
|
||||||
// No basal or temp basal is active yet
|
// No basal or temp basal is active yet
|
||||||
|
|
|
@ -16,16 +16,19 @@ import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||||
import info.nightscout.androidaps.logging.LTag;
|
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.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.AlertSet;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertSlot;
|
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.AlertType;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryStatus;
|
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.FirmwareVersion;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants;
|
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodCrc;
|
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.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
|
* @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() {
|
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 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
|
* @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
|
* 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()}
|
* indication on whether or not the pod is faulted, see {@link #isPodFaulted() isPodFaulted()}
|
||||||
*/
|
*/
|
||||||
public final boolean hasFaultEvent() {
|
public final boolean isFaulted() {
|
||||||
return podState != null && podState.getFaultEvent() != null;
|
return podState != null && podState.getFaultEventCode() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final PodInfoFaultEvent getFaultEvent() {
|
public final FaultEventCode getFaultEventCode() {
|
||||||
return getSafe(() -> podState.getFaultEvent());
|
return getSafe(() -> podState.getFaultEventCode());
|
||||||
}
|
|
||||||
|
|
||||||
public final void setFaultEvent(PodInfoFaultEvent faultEvent) {
|
|
||||||
setAndStore(() -> podState.setFaultEvent(faultEvent));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final AlertType getConfiguredAlertType(AlertSlot alertSlot) {
|
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);
|
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() {
|
public final PodProgressStatus getPodProgressStatus() {
|
||||||
return getSafe(() -> podState.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
|
* 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(() -> {
|
setSafe(() -> {
|
||||||
if (podState.getActivatedAt() == null) {
|
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.setActivatedAt(activatedAtCalculated);
|
||||||
}
|
}
|
||||||
podState.setSuspended(statusResponse.getDeliveryStatus() == DeliveryStatus.SUSPENDED);
|
podState.setSuspended(status.getDeliveryStatus() == DeliveryStatus.SUSPENDED);
|
||||||
podState.setActiveAlerts(statusResponse.getUnacknowledgedAlerts());
|
podState.setActiveAlerts(status.getUnacknowledgedAlerts());
|
||||||
podState.setLastDeliveryStatus(statusResponse.getDeliveryStatus());
|
podState.setLastDeliveryStatus(status.getDeliveryStatus());
|
||||||
podState.setReservoirLevel(statusResponse.getReservoirLevel());
|
podState.setReservoirLevel(status.getReservoirLevel());
|
||||||
podState.setTotalTicksDelivered(statusResponse.getTicksDelivered());
|
podState.setTotalTicksDelivered(status.getTicksDelivered());
|
||||||
podState.setPodProgressStatus(statusResponse.getPodProgressStatus());
|
podState.setPodProgressStatus(status.getPodProgressStatus());
|
||||||
podState.setTimeActive(statusResponse.getTimeActive());
|
podState.setTimeActive(status.getTimeActive());
|
||||||
if (statusResponse.getDeliveryStatus().isTbrRunning()) {
|
if (status.getDeliveryStatus().isTbrRunning()) {
|
||||||
if (!isTempBasalCertain() && isTempBasalRunning()) {
|
if (!isTempBasalCertain() && isTempBasalRunning()) {
|
||||||
podState.setTempBasalCertain(true);
|
podState.setTempBasalCertain(true);
|
||||||
}
|
}
|
||||||
|
@ -535,6 +552,13 @@ public abstract class PodStateManager {
|
||||||
setTempBasal(null, null, null, true, false);
|
setTempBasal(null, null, null, true, false);
|
||||||
}
|
}
|
||||||
podState.setLastUpdatedFromResponse(DateTime.now());
|
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 DateTimeZone timeZone;
|
||||||
private DateTime activatedAt;
|
private DateTime activatedAt;
|
||||||
private Duration timeActive;
|
private Duration timeActive;
|
||||||
private PodInfoFaultEvent faultEvent;
|
private FaultEventCode faultEventCode;
|
||||||
private Double reservoirLevel;
|
private Double reservoirLevel;
|
||||||
private Integer totalTicksDelivered;
|
private Integer totalTicksDelivered;
|
||||||
private boolean suspended;
|
private boolean suspended;
|
||||||
private NonceState nonceState;
|
private NonceState nonceState;
|
||||||
|
private ActivationProgress activationProgress = ActivationProgress.NONE;
|
||||||
private PodProgressStatus podProgressStatus;
|
private PodProgressStatus podProgressStatus;
|
||||||
private DeliveryStatus lastDeliveryStatus;
|
private DeliveryStatus lastDeliveryStatus;
|
||||||
private AlertSet activeAlerts;
|
private AlertSet activeAlerts;
|
||||||
|
@ -751,12 +776,12 @@ public abstract class PodStateManager {
|
||||||
this.timeActive = timeActive;
|
this.timeActive = timeActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
PodInfoFaultEvent getFaultEvent() {
|
FaultEventCode getFaultEventCode() {
|
||||||
return faultEvent;
|
return faultEventCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFaultEvent(PodInfoFaultEvent faultEvent) {
|
void setFaultEventCode(FaultEventCode faultEventCode) {
|
||||||
this.faultEvent = faultEvent;
|
this.faultEventCode = faultEventCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Double getReservoirLevel() {
|
Double getReservoirLevel() {
|
||||||
|
@ -799,6 +824,14 @@ public abstract class PodStateManager {
|
||||||
this.nonceState = nonceState;
|
this.nonceState = nonceState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ActivationProgress getActivationProgress() {
|
||||||
|
return activationProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setActivationProgress(ActivationProgress activationProgress) {
|
||||||
|
this.activationProgress = activationProgress;
|
||||||
|
}
|
||||||
|
|
||||||
PodProgressStatus getPodProgressStatus() {
|
PodProgressStatus getPodProgressStatus() {
|
||||||
return podProgressStatus;
|
return podProgressStatus;
|
||||||
}
|
}
|
||||||
|
@ -930,11 +963,12 @@ public abstract class PodStateManager {
|
||||||
", timeZone=" + timeZone +
|
", timeZone=" + timeZone +
|
||||||
", activatedAt=" + activatedAt +
|
", activatedAt=" + activatedAt +
|
||||||
", timeActive=" + timeActive +
|
", timeActive=" + timeActive +
|
||||||
", faultEvent=" + faultEvent +
|
", faultEventCode=" + faultEventCode +
|
||||||
", reservoirLevel=" + reservoirLevel +
|
", reservoirLevel=" + reservoirLevel +
|
||||||
", totalTicksDelivered=" + totalTicksDelivered +
|
", totalTicksDelivered=" + totalTicksDelivered +
|
||||||
", suspended=" + suspended +
|
", suspended=" + suspended +
|
||||||
", nonceState=" + nonceState +
|
", nonceState=" + nonceState +
|
||||||
|
", activationProgress=" + activationProgress +
|
||||||
", podProgressStatus=" + podProgressStatus +
|
", podProgressStatus=" + podProgressStatus +
|
||||||
", lastDeliveryStatus=" + lastDeliveryStatus +
|
", lastDeliveryStatus=" + lastDeliveryStatus +
|
||||||
", activeAlerts=" + activeAlerts +
|
", 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.FaultEventCode;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants;
|
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.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.BasalSchedule;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalScheduleEntry;
|
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.CommandFailedAfterChangingDeliveryStatusException;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.CrcMismatchException;
|
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.CrcMismatchException;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.DeliveryStatusVerificationFailedException;
|
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.IllegalPacketTypeException;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException;
|
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.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.IllegalVersionResponseTypeException;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.MessageDecodingException;
|
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.MessageDecodingException;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.NonceOutOfSyncException;
|
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.NonceOutOfSyncException;
|
||||||
|
@ -758,11 +759,9 @@ public class AapsOmnipodManager {
|
||||||
if (ex instanceof OmnipodException) {
|
if (ex instanceof OmnipodException) {
|
||||||
aapsLogger.error(LTag.PUMP, String.format("Caught OmnipodException[certainFailure=%s] from OmnipodManager", ((OmnipodException) ex).isCertainFailure()), ex);
|
aapsLogger.error(LTag.PUMP, String.format("Caught OmnipodException[certainFailure=%s] from OmnipodManager", ((OmnipodException) ex).isCertainFailure()), ex);
|
||||||
if (ex instanceof PodFaultException) {
|
if (ex instanceof PodFaultException) {
|
||||||
FaultEventCode faultEventCode = ((PodFaultException) ex).getFaultEvent().getFaultEventCode();
|
FaultEventCode faultEventCode = ((PodFaultException) ex).getDetailedStatus().getFaultEventCode();
|
||||||
if (!(faultEventCode == FaultEventCode.NO_FAULTS && podStateManager.isPodInitialized() && podStateManager.getPodProgressStatus() == PodProgressStatus.ACTIVATION_TIME_EXCEEDED)) {
|
|
||||||
showPodFaultNotification(faultEventCode);
|
showPodFaultNotification(faultEventCode);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
aapsLogger.error(LTag.PUMP, "Caught an unexpected non-OmnipodException from OmnipodManager", ex);
|
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);
|
comment = getStringResource(R.string.omnipod_error_crc_mismatch);
|
||||||
} else if (ex instanceof IllegalPacketTypeException) {
|
} else if (ex instanceof IllegalPacketTypeException) {
|
||||||
comment = getStringResource(R.string.omnipod_error_invalid_packet_type);
|
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);
|
comment = getStringResource(R.string.omnipod_error_invalid_progress_state);
|
||||||
} else if (ex instanceof IllegalVersionResponseTypeException) {
|
} else if (ex instanceof IllegalVersionResponseTypeException) {
|
||||||
comment = getStringResource(R.string.omnipod_error_invalid_response);
|
comment = getStringResource(R.string.omnipod_error_invalid_response);
|
||||||
|
@ -794,8 +794,10 @@ public class AapsOmnipodManager {
|
||||||
} else if (ex instanceof NotEnoughDataException) {
|
} else if (ex instanceof NotEnoughDataException) {
|
||||||
comment = getStringResource(R.string.omnipod_error_not_enough_data);
|
comment = getStringResource(R.string.omnipod_error_not_enough_data);
|
||||||
} else if (ex instanceof PodFaultException) {
|
} else if (ex instanceof PodFaultException) {
|
||||||
FaultEventCode faultEventCode = ((PodFaultException) ex).getFaultEvent().getFaultEventCode();
|
FaultEventCode faultEventCode = ((PodFaultException) ex).getDetailedStatus().getFaultEventCode();
|
||||||
comment = createPodFaultErrorMessage(faultEventCode);
|
comment = createPodFaultErrorMessage(faultEventCode);
|
||||||
|
} else if (ex instanceof ActivationTimeExceededException) {
|
||||||
|
comment = getStringResource(R.string.omnipod_error_pod_fault_activation_time_exceeded);
|
||||||
} else if (ex instanceof PodReturnedErrorResponseException) {
|
} else if (ex instanceof PodReturnedErrorResponseException) {
|
||||||
comment = getStringResource(R.string.omnipod_error_pod_returned_error_response);
|
comment = getStringResource(R.string.omnipod_error_pod_returned_error_response);
|
||||||
} else if (ex instanceof RileyLinkUnreachableException) {
|
} else if (ex instanceof RileyLinkUnreachableException) {
|
||||||
|
@ -816,9 +818,6 @@ public class AapsOmnipodManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String createPodFaultErrorMessage(FaultEventCode faultEventCode) {
|
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,
|
return getStringResource(R.string.omnipod_error_pod_fault,
|
||||||
ByteUtil.convertUnsignedByteToInt(faultEventCode.getValue()), faultEventCode.name());
|
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.ErrorResponse;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusUpdatableResponse;
|
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.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.communication.message.response.podinfo.PodInfoResponse;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.MessageBlockType;
|
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.OmnipodConstants;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PacketType;
|
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.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.IllegalMessageAddressException;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalMessageSequenceNumberException;
|
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalMessageSequenceNumberException;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPacketTypeException;
|
import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPacketTypeException;
|
||||||
|
@ -156,12 +157,21 @@ public class OmnipodRileyLinkCommunicationManager extends RileyLinkCommunication
|
||||||
podStateManager.setLastFailedCommunication(DateTime.now());
|
podStateManager.setLastFailedCommunication(DateTime.now());
|
||||||
throw new PodReturnedErrorResponseException(error);
|
throw new PodReturnedErrorResponseException(error);
|
||||||
}
|
}
|
||||||
} else if (responseMessageBlock.getType() == MessageBlockType.POD_INFO_RESPONSE && ((PodInfoResponse) responseMessageBlock).getSubType() == PodInfoType.FAULT_EVENT) {
|
} else if (responseMessageBlock.getType() == MessageBlockType.POD_INFO_RESPONSE && ((PodInfoResponse) responseMessageBlock).getSubType() == PodInfoType.DETAILED_STATUS) {
|
||||||
PodInfoFaultEvent faultEvent = (PodInfoFaultEvent) ((PodInfoResponse) responseMessageBlock).getPodInfo();
|
PodInfoDetailedStatus detailedStatus = (PodInfoDetailedStatus) ((PodInfoResponse) responseMessageBlock).getPodInfo();
|
||||||
podStateManager.setFaultEvent(faultEvent);
|
if (detailedStatus.isFaulted()) {
|
||||||
// Treat as successful communication as the user will get notified and can work with this response
|
// Treat as successful communication in order to prevent false positive pump unreachable alarms
|
||||||
podStateManager.setLastSuccessfulCommunication(DateTime.now());
|
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 {
|
} else {
|
||||||
podStateManager.setLastFailedCommunication(DateTime.now());
|
podStateManager.setLastFailedCommunication(DateTime.now());
|
||||||
throw new IllegalResponseException(responseClass.getSimpleName(), responseMessageBlock.getType());
|
throw new IllegalResponseException(responseClass.getSimpleName(), responseMessageBlock.getType());
|
||||||
|
@ -174,6 +184,7 @@ public class OmnipodRileyLinkCommunicationManager extends RileyLinkCommunication
|
||||||
} finally {
|
} finally {
|
||||||
podStateManager.storePodState();
|
podStateManager.storePodState();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private MessageBlock transportMessages(PodStateManager podStateManager, OmnipodMessage message, Integer addressOverride, Integer ackAddressOverride) {
|
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.common.hw.rileylink.service.RileyLinkServiceData
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodPumpPlugin
|
import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodPumpPlugin
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.R
|
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.OmnipodConstants
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus
|
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager
|
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager
|
||||||
|
@ -272,8 +273,8 @@ class OmnipodOverviewFragment : DaggerFragment() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (podStateManager.hasFaultEvent()) {
|
if (podStateManager.isFaulted) {
|
||||||
val faultEventCode = podStateManager.faultEvent.faultEventCode
|
val faultEventCode = podStateManager.faultEventCode
|
||||||
errors.add(resourceHelper.gs(R.string.omnipod_pod_status_pod_fault_description, faultEventCode.value, faultEventCode.name))
|
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) {
|
if (!podStateManager.isPodInitialized) {
|
||||||
resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_activation)
|
resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_activation)
|
||||||
} else {
|
} else {
|
||||||
if (PodProgressStatus.ACTIVATION_TIME_EXCEEDED == podStateManager.podProgressStatus) {
|
if (podStateManager.activationProgress.isBefore(ActivationProgress.PRIMING_COMPLETED)) {
|
||||||
resourceHelper.gs(R.string.omnipod_pod_status_activation_time_exceeded)
|
|
||||||
} else if (podStateManager.podProgressStatus.isBefore(PodProgressStatus.PRIMING_COMPLETED)) {
|
|
||||||
resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_activation)
|
resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_activation)
|
||||||
} else {
|
} else {
|
||||||
resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_cannula_insertion)
|
resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_cannula_insertion)
|
||||||
|
@ -454,7 +453,7 @@ class OmnipodOverviewFragment : DaggerFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateRefreshStatusButton() {
|
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()
|
&& 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.events.EventRileyLinkDeviceStatusChange
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData
|
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.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.driver.manager.PodStateManager
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged
|
import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.manager.AapsOmnipodManager
|
import info.nightscout.androidaps.plugins.pump.omnipod.manager.AapsOmnipodManager
|
||||||
|
@ -94,7 +95,7 @@ class PodManagementActivity : NoSplashAppCompatActivity() {
|
||||||
|
|
||||||
if (rileyLinkServiceData.rileyLinkServiceState.isReady) {
|
if (rileyLinkServiceData.rileyLinkServiceState.isReady) {
|
||||||
omnipod_pod_management_button_activate_pod.isEnabled = !podStateManager.isPodActivationCompleted
|
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) {
|
if (discardButtonEnabled) {
|
||||||
omnipod_pod_management_button_discard_pod.isEnabled = true
|
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 android.os.Bundle
|
||||||
import androidx.annotation.IdRes
|
import androidx.annotation.IdRes
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.R
|
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.driver.manager.PodStateManager
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.common.activity.OmnipodWizardActivityBase
|
import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.common.activity.OmnipodWizardActivityBase
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -25,7 +25,7 @@ class PodActivationWizardActivity : OmnipodWizardActivityBase() {
|
||||||
setContentView(R.layout.omnipod_pod_activation_wizard_activity)
|
setContentView(R.layout.omnipod_pod_activation_wizard_activity)
|
||||||
|
|
||||||
startDestination = savedInstanceState?.getInt(KEY_START_DESTINATION, R.id.fillPodInfoFragment)
|
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
|
R.id.fillPodInfoFragment
|
||||||
} else {
|
} else {
|
||||||
R.id.attachPodInfoFragment
|
R.id.attachPodInfoFragment
|
||||||
|
|
|
@ -3,8 +3,7 @@ package info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.activation.fra
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
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.PodProgressStatus
|
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager
|
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.common.fragment.ActionFragmentBase
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.deactivation.PodDeactivationWizardActivity
|
import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.deactivation.PodDeactivationWizardActivity
|
||||||
|
@ -27,8 +26,7 @@ abstract class PodActivationActionFragmentBase : ActionFragmentBase() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onActionFailure() {
|
override fun onActionFailure() {
|
||||||
if (podStateManager.isPodInitialized && podStateManager.podProgressStatus == PodProgressStatus.ACTIVATION_TIME_EXCEEDED) {
|
if (podStateManager.isPodActivationTimeExceeded && podStateManager.activationProgress.isAtLeast(ActivationProgress.PAIRING_COMPLETED)) {
|
||||||
omnipod_wizard_action_error.setText(R.string.omnipod_error_pod_fault_activation_time_exceeded)
|
|
||||||
omnipod_wizard_button_retry.visibility = View.GONE
|
omnipod_wizard_button_retry.visibility = View.GONE
|
||||||
omnipod_wizard_button_deactivate_pod.visibility = View.VISIBLE
|
omnipod_wizard_button_deactivate_pod.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,8 @@ public class OmnipodPumpPluginTest {
|
||||||
when(activePluginProvider.getActiveTreatments().getTempBasalFromHistory(anyLong())).thenReturn(null);
|
when(activePluginProvider.getActiveTreatments().getTempBasalFromHistory(anyLong())).thenReturn(null);
|
||||||
when(rileyLinkUtil.getRileyLinkHistory()).thenReturn(new ArrayList<>());
|
when(rileyLinkUtil.getRileyLinkHistory()).thenReturn(new ArrayList<>());
|
||||||
when(injector.androidInjector()).thenReturn(new AndroidInjector<Object>() {
|
when(injector.androidInjector()).thenReturn(new AndroidInjector<Object>() {
|
||||||
@Override public void inject(Object instance) {}
|
@Override public void inject(Object instance) {
|
||||||
|
}
|
||||||
});
|
});
|
||||||
Profile profile = mock(Profile.class);
|
Profile profile = mock(Profile.class);
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ public class GetStatusCommandTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPodInfoTypeFaultEvents() {
|
public void testPodInfoTypeFaultEvents() {
|
||||||
GetStatusCommand getStatusCommand = new GetStatusCommand(PodInfoType.FAULT_EVENT);
|
GetStatusCommand getStatusCommand = new GetStatusCommand(PodInfoType.DETAILED_STATUS);
|
||||||
|
|
||||||
assertArrayEquals(ByteUtil.fromHexString("0e0102"), getStatusCommand.getRawData());
|
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 org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
|
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 info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType;
|
||||||
|
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
@ -39,18 +38,18 @@ public class PodInfoResponseTest {
|
||||||
public void testMessageDecoding() {
|
public void testMessageDecoding() {
|
||||||
PodInfoResponse podInfoResponse = new PodInfoResponse(ByteUtil.fromHexString("0216020d0000000000ab6a038403ff03860000285708030d"));
|
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());
|
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
|
@Test
|
||||||
public void testInvalidPodInfoTypeMessageDecoding() {
|
public void testInvalidPodInfoTypeMessageDecoding() {
|
||||||
PodInfoResponse podInfoResponse = new PodInfoResponse(ByteUtil.fromHexString("0216020d0000000000ab6a038403ff03860000285708030d"));
|
PodInfoResponse podInfoResponse = new PodInfoResponse(ByteUtil.fromHexString("0216020d0000000000ab6a038403ff03860000285708030d"));
|
||||||
|
|
||||||
assertEquals(PodInfoType.FAULT_EVENT, podInfoResponse.getSubType());
|
assertEquals(PodInfoType.DETAILED_STATUS, podInfoResponse.getSubType());
|
||||||
|
|
||||||
thrown.expect(ClassCastException.class);
|
thrown.expect(ClassCastException.class);
|
||||||
PodInfoActiveAlerts podInfo = (PodInfoActiveAlerts) podInfoResponse.getPodInfo();
|
PodInfoActiveAlerts podInfo = (PodInfoActiveAlerts) podInfoResponse.getPodInfo();
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.common.events
|
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.defs.PumpDeviceState
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError
|
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.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 rileyLinkServiceState: RileyLinkServiceState? = null
|
||||||
var rileyLinkError: RileyLinkError? = null
|
var rileyLinkError: RileyLinkError? = null
|
||||||
|
|
||||||
|
@ -14,11 +17,10 @@ open class EventRileyLinkDeviceStatusChange : Event {
|
||||||
var errorDescription: String? = null
|
var errorDescription: String? = null
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constructor(rileyLinkTargetDevice: RileyLinkTargetDevice, rileyLinkServiceState: RileyLinkServiceState?, rileyLinkError: RileyLinkError?) {
|
||||||
constructor(rileyLinkServiceState: RileyLinkServiceState?, rileyLinkError: RileyLinkError?) {
|
this.rileyLinkTargetDevice = rileyLinkTargetDevice
|
||||||
this.rileyLinkServiceState = rileyLinkServiceState
|
this.rileyLinkServiceState = rileyLinkServiceState
|
||||||
this.rileyLinkError = rileyLinkError
|
this.rileyLinkError = rileyLinkError
|
||||||
}
|
}
|
||||||
|
@ -31,4 +33,17 @@ open class EventRileyLinkDeviceStatusChange : Event {
|
||||||
this.pumpDeviceState = pumpDeviceState
|
this.pumpDeviceState = pumpDeviceState
|
||||||
this.errorDescription = errorDescription
|
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.RileyLinkError;
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState;
|
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.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.resources.ResourceHelper;
|
||||||
import info.nightscout.androidaps.utils.sharedPreferences.SP;
|
import info.nightscout.androidaps.utils.sharedPreferences.SP;
|
||||||
|
|
||||||
|
@ -114,6 +112,10 @@ public abstract class RileyLinkService extends DaggerService {
|
||||||
|
|
||||||
public abstract RileyLinkCommunicationManager getDeviceCommunicationManager();
|
public abstract RileyLinkCommunicationManager getDeviceCommunicationManager();
|
||||||
|
|
||||||
|
public RileyLinkServiceState getRileyLinkServiceState() {
|
||||||
|
return rileyLinkServiceData == null ? null : rileyLinkServiceData.rileyLinkServiceState;
|
||||||
|
}
|
||||||
|
|
||||||
// Here is where the wake-lock begins:
|
// Here is where the wake-lock begins:
|
||||||
// We've received a service startCommand, we grab the lock.
|
// We've received a service startCommand, we grab the lock.
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -33,8 +33,7 @@ public class RileyLinkServiceData {
|
||||||
public RileyLinkServiceState rileyLinkServiceState = RileyLinkServiceState.NotStarted;
|
public RileyLinkServiceState rileyLinkServiceState = RileyLinkServiceState.NotStarted;
|
||||||
private long lastServiceStateChange = 0L;
|
private long lastServiceStateChange = 0L;
|
||||||
public RileyLinkFirmwareVersion firmwareVersion;
|
public RileyLinkFirmwareVersion firmwareVersion;
|
||||||
public RileyLinkTargetFrequency rileyLinkTargetFrequency; // TODO this might not be correct place
|
public RileyLinkTargetFrequency rileyLinkTargetFrequency;
|
||||||
|
|
||||||
public String rileylinkAddress;
|
public String rileylinkAddress;
|
||||||
long lastTuneUpTime = 0L;
|
long lastTuneUpTime = 0L;
|
||||||
public Double lastGoodFrequency;
|
public Double lastGoodFrequency;
|
||||||
|
@ -44,7 +43,7 @@ public class RileyLinkServiceData {
|
||||||
// radio version
|
// radio version
|
||||||
public RileyLinkFirmwareVersion versionCC110;
|
public RileyLinkFirmwareVersion versionCC110;
|
||||||
|
|
||||||
public RileyLinkTargetDevice targetDevice; // TODO this might not be correct place
|
public RileyLinkTargetDevice targetDevice;
|
||||||
|
|
||||||
// Medtronic Pump
|
// Medtronic Pump
|
||||||
public String pumpID;
|
public String pumpID;
|
||||||
|
@ -86,7 +85,7 @@ public class RileyLinkServiceData {
|
||||||
aapsLogger.info(LTag.PUMP, "RileyLink State Changed: {} {}", newState, errorCode == null ? "" : " - Error State: " + errorCode.name());
|
aapsLogger.info(LTag.PUMP, "RileyLink State Changed: {} {}", newState, errorCode == null ? "" : " - Error State: " + errorCode.name());
|
||||||
|
|
||||||
rileyLinkUtil.getRileyLinkHistory().add(new RLHistoryItem(rileyLinkServiceState, errorCode, targetDevice));
|
rileyLinkUtil.getRileyLinkHistory().add(new RLHistoryItem(rileyLinkServiceState, errorCode, targetDevice));
|
||||||
rxBus.send(new EventRileyLinkDeviceStatusChange(newState, errorCode));
|
rxBus.send(new EventRileyLinkDeviceStatusChange(targetDevice, newState, errorCode));
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue