From ffb518f50f78537dad99b511a07d415cb2ac99d5 Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Sat, 8 Aug 2020 15:26:51 +0200 Subject: [PATCH 01/17] Introduce PodStateManager --- .../omnipod/defs/state/PodStateManager.java | 98 +++ .../driver/comm/AapsPodStateManager.java | 566 ++++++++++++++++++ 2 files changed, 664 insertions(+) create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateManager.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateManager.java new file mode 100644 index 0000000000..e9b0149835 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateManager.java @@ -0,0 +1,98 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.defs.state; + +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.joda.time.Duration; + +import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoFaultEvent; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSet; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSlot; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertType; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.DeliveryStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.FirmwareVersion; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.SetupProgress; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BasalSchedule; + +public interface PodStateManager { + + boolean hasState(); + + void removeState(); + + boolean isPaired(); + + public int getAddress(); + + public int getMessageNumber(); + + public void setMessageNumber(int messageNumber); + + public int getPacketNumber(); + + public void setPacketNumber(int packetNumber); + + public void increaseMessageNumber(); + + public void increasePacketNumber(); + + void resyncNonce(int syncWord, int sentNonce, int sequenceNumber); + + int getCurrentNonce(); + + void advanceToNextNonce(); + + public boolean hasFaultEvent(); + + public PodInfoFaultEvent getFaultEvent(); + + public void setFaultEvent(PodInfoFaultEvent faultEvent); + + AlertType getConfiguredAlertType(AlertSlot alertSlot); + + void putConfiguredAlert(AlertSlot alertSlot, AlertType alertType); + + void removeConfiguredAlert(AlertSlot alertSlot); + + boolean hasActiveAlerts(); + + AlertSet getActiveAlerts(); + + Integer getLot(); + + Integer getTid(); + + FirmwareVersion getPiVersion(); + + FirmwareVersion getPmVersion(); + + DateTimeZone getTimeZone(); + + void setTimeZone(DateTimeZone timeZone); + + DateTime getTime(); + + DateTime getActivatedAt(); + + DateTime getExpiresAt(); + + String getExpiryDateAsString(); + + SetupProgress getSetupProgress(); + + void setSetupProgress(SetupProgress setupProgress); + + boolean isSuspended(); + + Double getReservoirLevel(); + + Duration getScheduleOffset(); + + BasalSchedule getBasalSchedule(); + + void setBasalSchedule(BasalSchedule basalSchedule); + + DeliveryStatus getLastDeliveryStatus(); + + void updateFromStatusResponse(StatusResponse statusResponse); +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java new file mode 100644 index 0000000000..253168653c --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java @@ -0,0 +1,566 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.driver.comm; + +import com.google.gson.Gson; + +import org.apache.commons.lang3.StringUtils; +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.joda.time.Duration; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import info.nightscout.androidaps.logging.AAPSLogger; +import info.nightscout.androidaps.logging.LTag; +import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoFaultEvent; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSet; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSlot; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertType; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.DeliveryStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.FirmwareVersion; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.SetupProgress; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BasalSchedule; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.util.OmniCRC; +import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; +import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil; +import info.nightscout.androidaps.utils.DateUtil; +import info.nightscout.androidaps.utils.sharedPreferences.SP; + +public class AapsPodStateManager implements PodStateManager { + + private final AAPSLogger aapsLogger; + private final SP sp; + private final OmnipodUtil omnipodUtil; + + private PodState podState; + + // TODO dagger + public AapsPodStateManager(AAPSLogger aapsLogger, SP sp, OmnipodUtil omnipodUtil) { + this.aapsLogger = aapsLogger; + this.sp = sp; + this.omnipodUtil = omnipodUtil; + + // TODO is there something like @PostConstruct in Dagger? if so, we should probably move loading the pod state there + loadPodState(); + } + + @Override public boolean hasState() { + return podState != null; + } + + @Override public void removeState() { + this.podState = null; + persistPodState(); + } + + @Override public boolean isPaired() { + return hasState() // + && podState.getLot() != null && podState.getTid() != null // + && podState.getPiVersion() != null && podState.getPmVersion() != null // + && podState.getTimeZone() != null // + && podState.getSetupProgress() != null; + } + + public void setPairingParameters(int lot, int tid, FirmwareVersion piVersion, FirmwareVersion pmVersion, DateTimeZone timeZone) { + if (!hasState()) { + throw new IllegalStateException("Cannot set pairing parameters: podState is null"); + } + if (isPaired()) { + throw new IllegalStateException("Cannot set pairing parameters: pairing parameters have already been set"); + } + if (piVersion == null) { + throw new IllegalArgumentException("Cannot set pairing parameters: piVersion can not be null"); + } + if (pmVersion == null) { + throw new IllegalArgumentException("Cannot set pairing parameters: pmVersion can not be null"); + } + if (timeZone == null) { + throw new IllegalArgumentException("Cannot set pairing parameters: timeZone can not be null"); + } + + podState.setLot(lot); + podState.setTid(tid); + podState.setPiVersion(piVersion); + podState.setPmVersion(pmVersion); + podState.setTimeZone(timeZone); + podState.setNonceState(new NonceState(lot, tid)); + podState.setSetupProgress(SetupProgress.ADDRESS_ASSIGNED); + } + + @Override public int getAddress() { + return getSafe(() -> podState.getAddress()); + } + + @Override public int getMessageNumber() { + return getSafe(() -> podState.getMessageNumber()); + } + + @Override public void setMessageNumber(int messageNumber) { + setAndStore(() -> podState.setMessageNumber(messageNumber)); + } + + @Override public int getPacketNumber() { + return getSafe(() -> podState.getPacketNumber()); + } + + @Override public void setPacketNumber(int packetNumber) { + setAndStore(() -> podState.setPacketNumber(packetNumber)); + } + + @Override public void increaseMessageNumber() { + setAndStore(() -> podState.setMessageNumber(podState.getMessageNumber() + 1)); + } + + @Override public void increasePacketNumber() { + setAndStore(() -> podState.setPacketNumber(podState.getPacketNumber() + 1)); + } + + @Override public void resyncNonce(int syncWord, int sentNonce, int sequenceNumber) { + if (!isPaired()) { + throw new IllegalStateException("Cannot resync nonce: Pod is not paired yet"); + } + + int sum = (sentNonce & 0xFFFF) + + OmniCRC.crc16lookup[sequenceNumber] + + (podState.getLot() & 0xFFFF) + + (podState.getTid() & 0xFFFF); + int seed = ((sum & 0xFFFF) ^ syncWord); + NonceState nonceState = new NonceState(podState.getLot(), podState.getTid(), (byte) (seed & 0xFF)); + + setAndStore(() -> podState.setNonceState(nonceState)); + } + + @Override public int getCurrentNonce() { + if (!isPaired()) { + throw new IllegalStateException("Cannot get current nonce: Pod is not paired yet"); + } + return podState.getNonceState().getCurrentNonce(); + } + + @Override public void advanceToNextNonce() { + if (!isPaired()) { + throw new IllegalStateException("Cannot advance to next nonce: Pod is not paired yet"); + } + setAndStore(() -> podState.getNonceState().advanceToNextNonce()); + } + + @Override public boolean hasFaultEvent() { + return getSafe(() -> podState.getFaultEvent()) != null; + } + + @Override public PodInfoFaultEvent getFaultEvent() { + return getSafe(() -> podState.getFaultEvent()); + } + + @Override public void setFaultEvent(PodInfoFaultEvent faultEvent) { + setAndStore(() -> podState.setFaultEvent(faultEvent)); + } + + @Override public AlertType getConfiguredAlertType(AlertSlot alertSlot) { + return getSafe(() -> podState.getConfiguredAlerts().get(alertSlot)); + } + + @Override public void putConfiguredAlert(AlertSlot alertSlot, AlertType alertType) { + setAndStore(() -> podState.getConfiguredAlerts().put(alertSlot, alertType)); + } + + @Override public void removeConfiguredAlert(AlertSlot alertSlot) { + setAndStore(() -> podState.getConfiguredAlerts().remove(alertSlot)); + } + + @Override public boolean hasActiveAlerts() { + AlertSet activeAlerts = podState.getActiveAlerts(); + return activeAlerts != null && activeAlerts.size() > 0; + } + + @Override public AlertSet getActiveAlerts() { + return getSafe(() -> podState.getActiveAlerts()); + } + + @Override public Integer getLot() { + return getSafe(() -> podState.getLot()); + } + + @Override public Integer getTid() { + return getSafe(() -> podState.getTid()); + } + + @Override public FirmwareVersion getPiVersion() { + return getSafe(() -> podState.getPiVersion()); + } + + @Override public FirmwareVersion getPmVersion() { + return getSafe(() -> podState.getPmVersion()); + } + + @Override public DateTimeZone getTimeZone() { + return getSafe(() -> podState.getTimeZone()); + } + + @Override public void setTimeZone(DateTimeZone timeZone) { + if (timeZone == null) { + throw new IllegalArgumentException("Time zone can not be null"); + } + setAndStore(() -> podState.setTimeZone(timeZone)); + } + + @Override public DateTime getTime() { + DateTime now = DateTime.now(); + return now.withZone(getSafe(() -> podState.getTimeZone())); + } + + public DateTime getActivatedAt() { + DateTime activatedAt = getSafe(() -> podState.getActivatedAt()); + return activatedAt == null ? null : activatedAt.withZone(getSafe(() -> podState.getTimeZone())); + } + + public DateTime getExpiresAt() { + DateTime expiresAt = getSafe(() -> podState.getExpiresAt()); + return expiresAt == null ? null : expiresAt.withZone(getSafe(() -> podState.getTimeZone())); + } + + // TODO doesn't belong here + public String getExpiryDateAsString() { + DateTime expiresAt = getExpiresAt(); + return expiresAt == null ? "???" : DateUtil.dateAndTimeString(expiresAt.toDate()); + } + + public SetupProgress getSetupProgress() { + return getSafe(() -> podState.getSetupProgress()); + } + + public void setSetupProgress(SetupProgress setupProgress) { + if (setupProgress == null) { + throw new IllegalArgumentException("Setup progress can not be null"); + } + setAndStore(() -> podState.setSetupProgress(setupProgress)); + } + + @Override public boolean isSuspended() { + return getSafe(() -> podState.isSuspended()); + } + + @Override public Double getReservoirLevel() { + return getSafe(() -> podState.getReservoirLevel()); + } + + @Override public Duration getScheduleOffset() { + DateTime now = getTime(); + DateTime startOfDay = new DateTime(now.getYear(), now.getMonthOfYear(), now.getDayOfMonth(), + 0, 0, 0, getSafe(() -> podState.getTimeZone())); + return new Duration(startOfDay, now); + } + + @Override public BasalSchedule getBasalSchedule() { + return getSafe(() -> podState.getBasalSchedule()); + } + + @Override public void setBasalSchedule(BasalSchedule basalSchedule) { + setAndStore(() -> podState.setBasalSchedule(basalSchedule)); + } + + @Override public DeliveryStatus getLastDeliveryStatus() { + return getSafe(() -> podState.getLastDeliveryStatus()); + } + + @Override public void updateFromStatusResponse(StatusResponse statusResponse) { + if (!hasState()) { + throw new IllegalStateException("Cannot update from status response: podState is null"); + } + setAndStore(() -> { + if (podState.getActivatedAt() == null) { + DateTime activatedAtCalculated = getTime().minus(statusResponse.getTimeActive()); + podState.setActivatedAt(activatedAtCalculated); + } + DateTime expiresAt = podState.getExpiresAt(); + DateTime expiresAtCalculated = podState.getActivatedAt().plus(OmnipodConst.NOMINAL_POD_LIFE); + if (expiresAt == null || expiresAtCalculated.isBefore(expiresAt) || expiresAtCalculated.isAfter(expiresAt.plusMinutes(1))) { + podState.setExpiresAt(expiresAtCalculated); + } + + boolean newSuspendedState = statusResponse.getDeliveryStatus() == DeliveryStatus.SUSPENDED; + if (podState.isSuspended() != newSuspendedState) { + aapsLogger.info(LTag.PUMPCOMM, "Updating pod suspended state in updateFromStatusResponse. newSuspendedState={}, statusResponse={}", newSuspendedState, statusResponse.toString()); + podState.setSuspended(newSuspendedState); + } + podState.setActiveAlerts(statusResponse.getAlerts()); + podState.setLastDeliveryStatus(statusResponse.getDeliveryStatus()); + podState.setReservoirLevel(statusResponse.getReservoirLevel()); + }); + } + + private void setAndStore(Runnable runnable) { + if (!hasState()) { + throw new IllegalStateException("Cannot mutate PodState: podState is null"); + } + runnable.run(); + persistPodState(); + } + + // Not actually "safe" as it throws an Exception, but it prevents NPEs + private T getSafe(Supplier supplier) { + if (!hasState()) { + throw new IllegalStateException("Cannot read from PodState: podState is null"); + } + return supplier.get(); + } + + private void persistPodState() { + Gson gson = omnipodUtil.getGsonInstance(); + String gsonValue = gson.toJson(podState); + aapsLogger.info(LTag.PUMPCOMM, "PodState-SP: Saved PodState to SharedPreferences: " + gsonValue); + sp.putString(OmnipodConst.Prefs.PodState, gsonValue); + } + + private void loadPodState() { + podState = null; + + String storedPodState = sp.getString(OmnipodConst.Prefs.PodState, ""); + + if (StringUtils.isEmpty(storedPodState)) { + aapsLogger.info(LTag.PUMP, "PodState-SP: no PodState present in SharedPreferences"); + } else { + aapsLogger.info(LTag.PUMP, "PodState-SP: loaded PodState from SharedPreferences: " + storedPodState); + try { + podState = omnipodUtil.getGsonInstance().fromJson(storedPodState, PodState.class); + } catch (Exception ex) { + aapsLogger.error(LTag.PUMPCOMM, "PodState-SP: could not deserialize PodState", ex); + } + } + } + + private static class PodState { + private final int address; + private Integer lot; + private Integer tid; + private FirmwareVersion piVersion; + private FirmwareVersion pmVersion; + private int packetNumber; + private int messageNumber; + private DateTimeZone timeZone; + private DateTime activatedAt; + private DateTime expiresAt; + private PodInfoFaultEvent faultEvent; + private Double reservoirLevel; + private boolean suspended; + private NonceState nonceState; + private SetupProgress setupProgress; + private DeliveryStatus lastDeliveryStatus; + private AlertSet activeAlerts; + private BasalSchedule basalSchedule; + private final Map configuredAlerts = new HashMap<>(); + + private PodState(int address) { + this.address = address; + } + + public int getAddress() { + return address; + } + + public Integer getLot() { + return lot; + } + + public void setLot(int lot) { + this.lot = lot; + } + + public Integer getTid() { + return tid; + } + + public void setTid(int tid) { + this.tid = tid; + } + + public FirmwareVersion getPiVersion() { + return piVersion; + } + + public void setPiVersion(FirmwareVersion piVersion) { + if (this.piVersion != null) { + throw new IllegalStateException("piVersion has already been set"); + } + if (piVersion == null) { + throw new IllegalArgumentException("piVersion can not be null"); + } + this.piVersion = piVersion; + } + + public FirmwareVersion getPmVersion() { + return pmVersion; + } + + public void setPmVersion(FirmwareVersion pmVersion) { + this.pmVersion = pmVersion; + } + + public int getPacketNumber() { + return packetNumber; + } + + public void setPacketNumber(int packetNumber) { + this.packetNumber = packetNumber; + } + + public int getMessageNumber() { + return messageNumber; + } + + public void setMessageNumber(int messageNumber) { + this.messageNumber = messageNumber; + } + + public DateTimeZone getTimeZone() { + return timeZone; + } + + public void setTimeZone(DateTimeZone timeZone) { + this.timeZone = timeZone; + } + + public DateTime getActivatedAt() { + return activatedAt; + } + + public void setActivatedAt(DateTime activatedAt) { + this.activatedAt = activatedAt; + } + + public DateTime getExpiresAt() { + return expiresAt; + } + + public void setExpiresAt(DateTime expiresAt) { + this.expiresAt = expiresAt; + } + + public PodInfoFaultEvent getFaultEvent() { + return faultEvent; + } + + public void setFaultEvent(PodInfoFaultEvent faultEvent) { + this.faultEvent = faultEvent; + } + + public Double getReservoirLevel() { + return reservoirLevel; + } + + public void setReservoirLevel(Double reservoirLevel) { + this.reservoirLevel = reservoirLevel; + } + + public boolean isSuspended() { + return suspended; + } + + public void setSuspended(boolean suspended) { + this.suspended = suspended; + } + + public NonceState getNonceState() { + return nonceState; + } + + public void setNonceState(NonceState nonceState) { + this.nonceState = nonceState; + } + + public SetupProgress getSetupProgress() { + return setupProgress; + } + + public void setSetupProgress(SetupProgress setupProgress) { + this.setupProgress = setupProgress; + } + + public DeliveryStatus getLastDeliveryStatus() { + return lastDeliveryStatus; + } + + public void setLastDeliveryStatus(DeliveryStatus lastDeliveryStatus) { + this.lastDeliveryStatus = lastDeliveryStatus; + } + + public AlertSet getActiveAlerts() { + return activeAlerts; + } + + public void setActiveAlerts(AlertSet activeAlerts) { + this.activeAlerts = activeAlerts; + } + + public BasalSchedule getBasalSchedule() { + return basalSchedule; + } + + public void setBasalSchedule(BasalSchedule basalSchedule) { + this.basalSchedule = basalSchedule; + } + + public Map getConfiguredAlerts() { + return configuredAlerts; + } + } + + private static class NonceState { + private final long[] table = new long[21]; + private int index; + + private NonceState(int lot, int tid) { + initializeTable(lot, tid, (byte) 0x00); + } + + private NonceState(int lot, int tid, byte seed) { + initializeTable(lot, tid, seed); + } + + private void initializeTable(int lot, int tid, byte seed) { + table[0] = (long) (lot & 0xFFFF) + 0x55543DC3L + (((long) (lot) & 0xFFFFFFFFL) >> 16); + table[0] = table[0] & 0xFFFFFFFFL; + table[1] = (tid & 0xFFFF) + 0xAAAAE44EL + (((long) (tid) & 0xFFFFFFFFL) >> 16); + table[1] = table[1] & 0xFFFFFFFFL; + index = 0; + table[0] += seed; + for (int i = 0; i < 16; i++) { + table[2 + i] = generateEntry(); + } + index = (int) ((table[0] + table[1]) & 0X0F); + } + + private int generateEntry() { + table[0] = (((table[0] >> 16) + (table[0] & 0xFFFF) * 0x5D7FL) & 0xFFFFFFFFL); + table[1] = (((table[1] >> 16) + (table[1] & 0xFFFF) * 0x8CA0L) & 0xFFFFFFFFL); + return (int) ((table[1] + (table[0] << 16)) & 0xFFFFFFFFL); + } + + public int getCurrentNonce() { + return (int) table[(2 + index)]; + } + + public void advanceToNextNonce() { + int nonce = getCurrentNonce(); + table[(2 + index)] = generateEntry(); + index = (nonce & 0x0F); + } + + @Override + public String toString() { + return "NonceState{" + + "table=" + Arrays.toString(table) + + ", index=" + index + + '}'; + } + } + + // TODO replace with java.util.function.Supplier when min API level >= 24 + @FunctionalInterface + private interface Supplier { + T get(); + } +} From a06d78b0b7b29c4a8d7413f58888fa553a5b0ad3 Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Sat, 8 Aug 2020 15:42:53 +0200 Subject: [PATCH 02/17] Add dagger annotations in AapsPodStateManager --- .../omnipod/driver/comm/AapsPodStateManager.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java index 253168653c..75479709e2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java @@ -11,6 +11,9 @@ import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import javax.inject.Inject; + +import dagger.android.HasAndroidInjector; import info.nightscout.androidaps.logging.AAPSLogger; import info.nightscout.androidaps.logging.LTag; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; @@ -31,17 +34,14 @@ import info.nightscout.androidaps.utils.sharedPreferences.SP; public class AapsPodStateManager implements PodStateManager { - private final AAPSLogger aapsLogger; - private final SP sp; - private final OmnipodUtil omnipodUtil; + @Inject private AAPSLogger aapsLogger; + @Inject private SP sp; + @Inject private OmnipodUtil omnipodUtil; private PodState podState; - // TODO dagger - public AapsPodStateManager(AAPSLogger aapsLogger, SP sp, OmnipodUtil omnipodUtil) { - this.aapsLogger = aapsLogger; - this.sp = sp; - this.omnipodUtil = omnipodUtil; + public AapsPodStateManager(HasAndroidInjector injector) { + injector.androidInjector().inject(this); // TODO is there something like @PostConstruct in Dagger? if so, we should probably move loading the pod state there loadPodState(); From 337c61d5004ad08f2c10e6c7d1855c8d6f429262 Mon Sep 17 00:00:00 2001 From: Andy Rozman Date: Sat, 8 Aug 2020 15:16:50 +0100 Subject: [PATCH 03/17] - added dependency --- .../nightscout/androidaps/dependencyInjection/OmnipodModule.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/OmnipodModule.kt b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/OmnipodModule.kt index 9fa0ae8da4..447e901737 100644 --- a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/OmnipodModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/OmnipodModule.kt @@ -12,6 +12,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.pages.Init import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.pages.PodInfoFragment import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.removepod.RemoveActionFragment import info.nightscout.androidaps.plugins.pump.omnipod.driver.comm.AapsOmnipodManager +import info.nightscout.androidaps.plugins.pump.omnipod.driver.comm.AapsPodStateManager import info.nightscout.androidaps.plugins.pump.omnipod.driver.ui.OmnipodUITask @Module @@ -37,4 +38,6 @@ abstract class OmnipodModule { @ContributesAndroidInjector abstract fun podSessionState(): PodSessionState @ContributesAndroidInjector abstract fun initPodTask() : InitPodTask + @ContributesAndroidInjector abstract fun initAapsPodStateManager() : AapsPodStateManager + } From b50670cceba37c1854e4ef56731c83db66c158c8 Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Sat, 8 Aug 2020 18:06:14 +0200 Subject: [PATCH 04/17] Replace PodState with PodStateManager --- .../dependencyInjection/OmnipodModule.kt | 4 +- .../plugins/pump/omnipod/OmnipodFragment.kt | 27 +- .../pump/omnipod/OmnipodPumpPlugin.java | 26 +- .../comm/OmnipodCommunicationManager.java | 101 +++--- .../pump/omnipod/comm/OmnipodManager.java | 134 ++++---- .../comm/action/AcknowledgeAlertsAction.java | 22 +- .../comm/action/AssignAddressAction.java | 54 ++-- .../pump/omnipod/comm/action/BolusAction.java | 26 +- .../comm/action/CancelDeliveryAction.java | 24 +- .../comm/action/ConfigureAlertsAction.java | 20 +- .../comm/action/DeactivatePodAction.java | 24 +- .../omnipod/comm/action/GetPodInfoAction.java | 16 +- .../omnipod/comm/action/GetStatusAction.java | 12 +- .../comm/action/InsertCannulaAction.java | 48 +-- .../pump/omnipod/comm/action/PrimeAction.java | 44 +-- .../comm/action/SetBasalScheduleAction.java | 24 +- .../comm/action/SetTempBasalAction.java | 20 +- .../omnipod/comm/action/SetupPodAction.java | 35 +- .../action/service/InsertCannulaService.java | 18 +- .../comm/action/service/PrimeService.java | 20 +- .../omnipod/defs/state/PodSessionState.java | 299 ------------------ .../omnipod/defs/state/PodSetupState.java | 43 --- .../pump/omnipod/defs/state/PodState.java | 68 ---- .../defs/state/PodStateChangedHandler.java | 2 +- .../omnipod/defs/state/PodStateManager.java | 26 +- .../omnipod/dialogs/PodManagementActivity.kt | 15 +- .../wizard/pages/InitPodRefreshAction.java | 2 +- .../dialogs/wizard/pages/PodInfoFragment.java | 35 +- .../omnipod/driver/OmnipodPumpStatus.java | 7 +- .../driver/comm/AapsOmnipodManager.java | 91 +++--- .../driver/comm/AapsPodStateManager.java | 103 ++++-- .../events/EventOmnipodDeviceStatusChange.kt | 10 +- .../service/RileyLinkOmnipodService.java | 15 +- .../pump/omnipod/util/OmnipodUtil.java | 66 +--- .../comm/OmnipodDashCommunicationManager.java | 4 +- ...Test.java => AapsPodStateManagerTest.java} | 44 ++- 36 files changed, 550 insertions(+), 979 deletions(-) delete mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodSessionState.java delete mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodSetupState.java delete mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodState.java rename app/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/{PodSessionStateTest.java => AapsPodStateManagerTest.java} (62%) diff --git a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/OmnipodModule.kt b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/OmnipodModule.kt index 447e901737..e458957fb9 100644 --- a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/OmnipodModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/OmnipodModule.kt @@ -3,7 +3,7 @@ package info.nightscout.androidaps.dependencyInjection import dagger.Module import dagger.android.ContributesAndroidInjector import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.PodHistoryActivity import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.PodManagementActivity import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.initpod.InitActionFragment @@ -35,7 +35,7 @@ abstract class OmnipodModule { // Data @ContributesAndroidInjector abstract fun omnipodUITaskProvider(): OmnipodUITask @ContributesAndroidInjector abstract fun initPodRefreshAction(): InitPodRefreshAction - @ContributesAndroidInjector abstract fun podSessionState(): PodSessionState + @ContributesAndroidInjector abstract fun podStateManager(): PodStateManager @ContributesAndroidInjector abstract fun initPodTask() : InitPodTask @ContributesAndroidInjector abstract fun initAapsPodStateManager() : AapsPodStateManager diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt index 667961be61..27b7558d62 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt @@ -263,20 +263,17 @@ class OmnipodFragment : DaggerFragment() { omnipodPumpStatus.podAvailable = false omnipodPumpStatus.podNumber == null } else if (driverState == OmnipodDriverState.Initalized_PodInitializing) { - omnipod_pod_address.text = omnipodPumpStatus.podSessionState.address.toString() + omnipod_pod_address.text = omnipodPumpStatus.podStateManager.address.toString() omnipod_pod_expiry.text = "-" - omnipod_pod_status.text = resourceHelper.gs(R.string.omnipod_pod_status_initalizing) + " (" + omnipodPumpStatus.podSessionState.getSetupProgress().name + ")" + omnipod_pod_status.text = resourceHelper.gs(R.string.omnipod_pod_status_initalizing) + " (" + omnipodPumpStatus.podStateManager.getSetupProgress().name + ")" omnipodPumpStatus.podAvailable = false - omnipodPumpStatus.podNumber == omnipodPumpStatus.podSessionState.address.toString() + omnipodPumpStatus.podNumber == omnipodPumpStatus.podStateManager.address.toString() } else { - omnipodPumpStatus.podLotNumber = "" + omnipodPumpStatus.podSessionState.lot + omnipodPumpStatus.podLotNumber = "" + omnipodPumpStatus.podStateManager.lot omnipodPumpStatus.podAvailable = true - omnipod_pod_address.text = omnipodPumpStatus.podSessionState.address.toString() - omnipod_pod_expiry.text = omnipodPumpStatus.podSessionState.expiryDateAsString - omnipodPumpStatus.podNumber = omnipodPumpStatus.podSessionState.address.toString() - - //pumpStatus.podSessionState = checkStatusSet(pumpStatus.podSessionState, - // OmnipodUtil.getPodSessionState()) as PodSessionState? + omnipod_pod_address.text = omnipodPumpStatus.podStateManager.address.toString() + omnipod_pod_expiry.text = omnipodPumpStatus.podStateManager.expiryDateAsString + omnipodPumpStatus.podNumber = omnipodPumpStatus.podStateManager.address.toString() var podDeviceState = omnipodPumpStatus.podDeviceState @@ -317,13 +314,13 @@ class OmnipodFragment : DaggerFragment() { } } - if (SetupProgress.COMPLETED.equals(omnipodPumpStatus.podSessionState.getSetupProgress())) { - if(omnipodPumpStatus.podSessionState.lastDeliveryStatus != null) { - stateText += " (last delivery status: " + omnipodPumpStatus.podSessionState.lastDeliveryStatus.name + ")" + if (SetupProgress.COMPLETED.equals(omnipodPumpStatus.podStateManager.getSetupProgress())) { + if(omnipodPumpStatus.podStateManager.lastDeliveryStatus != null) { + stateText += " (last delivery status: " + omnipodPumpStatus.podStateManager.lastDeliveryStatus.name + ")" } } else { - if(omnipodPumpStatus.podSessionState.setupProgress != null) { - stateText += " (setup progress: " + omnipodPumpStatus.podSessionState.setupProgress.name + ")" + if(omnipodPumpStatus.podStateManager.setupProgress != null) { + stateText += " (setup progress: " + omnipodPumpStatus.podStateManager.setupProgress.name + ")" } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java index 521db02a60..a7a0eba086 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java @@ -49,7 +49,6 @@ import info.nightscout.androidaps.plugins.general.overview.notifications.Notific import info.nightscout.androidaps.plugins.pump.common.PumpPluginAbstract; import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus; import info.nightscout.androidaps.plugins.pump.common.data.TempBasalPair; -import info.nightscout.androidaps.plugins.pump.common.defs.DeviceCommandExecutor; import info.nightscout.androidaps.plugins.pump.common.defs.PumpDriverState; import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst; @@ -64,7 +63,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodCommunication import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodCustomActionType; import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodPumpPluginInterface; import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodStatusRequest; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodDriverState; import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus; import info.nightscout.androidaps.plugins.pump.omnipod.driver.ui.OmnipodUIComm; @@ -488,17 +487,17 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump public boolean isSuspended() { return (omnipodUtil.getDriverState() == OmnipodDriverState.Initalized_NoPod) || - (omnipodUtil.getPodSessionState() != null && omnipodUtil.getPodSessionState().isSuspended()); + (omnipodUtil.getPodStateManager() != null && omnipodUtil.getPodStateManager().isSuspended()); // return (pumpStatusLocal != null && !pumpStatusLocal.podAvailable) || -// (OmnipodUtil.getPodSessionState() != null && OmnipodUtil.getPodSessionState().isSuspended()); +// (OmnipodUtil.getPodStateManager() != null && OmnipodUtil.getPodStateManager().isSuspended()); // // TODO ddd // return (OmnipodUtil.getDriverState() == OmnipodDriverState.Initalized_NoPod) || -// (OmnipodUtil.getPodSessionState() != null && OmnipodUtil.getPodSessionState().isSuspended()); +// (OmnipodUtil.getPodStateManager() != null && OmnipodUtil.getPodStateManager().isSuspended()); // // return (pumpStatusLocal != null && !pumpStatusLocal.podAvailable) || -// (OmnipodUtil.getPodSessionState() != null && OmnipodUtil.getPodSessionState().isSuspended()); +// (OmnipodUtil.getPodStateManager() != null && OmnipodUtil.getPodStateManager().isSuspended()); } @Override @@ -622,18 +621,9 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump setRefreshButtonEnabled(false); - PodSessionState podSessionState = null; - - if (omnipodUtil.getPodSessionState() != null) { - podSessionState = omnipodUtil.getPodSessionState(); - } else { - podSessionState = omnipodUtil.loadSessionState(); - } - - - if (podSessionState != null) { - aapsLogger.debug(LTag.PUMP, "PodSessionState (saved): " + podSessionState); + PodStateManager podStateManager = omnipodUtil.getPodStateManager(); + if (podStateManager != null) { if (!isRefresh) { pumpState = PumpDriverState.Initialized; } @@ -642,7 +632,7 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump getPodPumpStatus(); } else { - aapsLogger.debug(LTag.PUMP, "No PodSessionState found. Pod probably not running."); + aapsLogger.error(LTag.PUMP, "No PodStateManager found"); omnipodUtil.setDriverState(OmnipodDriverState.Initalized_NoPod); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodCommunicationManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodCommunicationManager.java index e77befd258..6968532adb 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodCommunicationManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodCommunicationManager.java @@ -16,11 +16,8 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RileyLink import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.RLMessage; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RLMessageType; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkBLEError; -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData; -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.ServiceTaskExecutor; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpDeviceState; -import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodPumpPlugin; import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.OmnipodAction; import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.CommunicationException; import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalMessageAddressException; @@ -43,7 +40,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.pod import info.nightscout.androidaps.plugins.pump.omnipod.defs.MessageBlockType; import info.nightscout.androidaps.plugins.pump.omnipod.defs.PacketType; import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodState; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus; import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; @@ -103,13 +100,13 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager { this.omnipodPumpStatus.setPumpDeviceState(pumpDeviceState); } - public T sendCommand(Class responseClass, PodState podState, MessageBlock command) { - return sendCommand(responseClass, podState, command, true); + public T sendCommand(Class responseClass, PodStateManager podStateManager, MessageBlock command) { + return sendCommand(responseClass, podStateManager, command, true); } - public T sendCommand(Class responseClass, PodState podState, MessageBlock command, boolean automaticallyResyncNone) { - OmnipodMessage message = new OmnipodMessage(podState.getAddress(), Collections.singletonList(command), podState.getMessageNumber()); - return exchangeMessages(responseClass, podState, message, automaticallyResyncNone); + public T sendCommand(Class responseClass, PodStateManager podStateManager, MessageBlock command, boolean automaticallyResyncNone) { + OmnipodMessage message = new OmnipodMessage(podStateManager.getAddress(), Collections.singletonList(command), podStateManager.getMessageNumber()); + return exchangeMessages(responseClass, podStateManager, message, automaticallyResyncNone); } // Convenience method @@ -117,33 +114,33 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager { return action.execute(this); } - public T exchangeMessages(Class responseClass, PodState podState, OmnipodMessage message) { - return exchangeMessages(responseClass, podState, message, true); + public T exchangeMessages(Class responseClass, PodStateManager podStateManager, OmnipodMessage message) { + return exchangeMessages(responseClass, podStateManager, message, true); } - public T exchangeMessages(Class responseClass, PodState podState, OmnipodMessage message, boolean automaticallyResyncNonce) { - return exchangeMessages(responseClass, podState, message, null, null, automaticallyResyncNonce); + public T exchangeMessages(Class responseClass, PodStateManager podStateManager, OmnipodMessage message, boolean automaticallyResyncNonce) { + return exchangeMessages(responseClass, podStateManager, message, null, null, automaticallyResyncNonce); } - public synchronized T exchangeMessages(Class responseClass, PodState podState, OmnipodMessage message, Integer addressOverride, Integer ackAddressOverride) { - return exchangeMessages(responseClass, podState, message, addressOverride, ackAddressOverride, true); + public synchronized T exchangeMessages(Class responseClass, PodStateManager podStateManager, OmnipodMessage message, Integer addressOverride, Integer ackAddressOverride) { + return exchangeMessages(responseClass, podStateManager, message, addressOverride, ackAddressOverride, true); } - public synchronized T exchangeMessages(Class responseClass, PodState podState, OmnipodMessage message, Integer addressOverride, Integer ackAddressOverride, boolean automaticallyResyncNonce) { + public synchronized T exchangeMessages(Class responseClass, PodStateManager podStateManager, OmnipodMessage message, Integer addressOverride, Integer ackAddressOverride, boolean automaticallyResyncNonce) { - aapsLogger.debug(LTag.PUMPCOMM, "Exchanging OmnipodMessage [responseClass={}, podState={}, message={}, addressOverride={}, ackAddressOverride={}, automaticallyResyncNonce={}]: {}", // - responseClass.getSimpleName(), podState, message, addressOverride, ackAddressOverride, automaticallyResyncNonce, message); + aapsLogger.debug(LTag.PUMPCOMM, "Exchanging OmnipodMessage [responseClass={}, podStateManager={}, message={}, addressOverride={}, ackAddressOverride={}, automaticallyResyncNonce={}]: {}", // + responseClass.getSimpleName(), podStateManager, message, addressOverride, ackAddressOverride, automaticallyResyncNonce, message); for (int i = 0; 2 > i; i++) { - if (podState.hasNonceState() && message.isNonceResyncable()) { - podState.advanceToNextNonce(); + if (podStateManager.isPaired() && message.isNonceResyncable()) { + podStateManager.advanceToNextNonce(); } - MessageBlock responseMessageBlock = transportMessages(podState, message, addressOverride, ackAddressOverride); + MessageBlock responseMessageBlock = transportMessages(podStateManager, message, addressOverride, ackAddressOverride); if (responseMessageBlock instanceof StatusResponse) { - podState.updateFromStatusResponse((StatusResponse) responseMessageBlock); + podStateManager.updateFromStatusResponse((StatusResponse) responseMessageBlock); } if (responseClass.isInstance(responseMessageBlock)) { @@ -152,9 +149,9 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager { if (responseMessageBlock.getType() == MessageBlockType.ERROR_RESPONSE) { ErrorResponse error = (ErrorResponse) responseMessageBlock; if (error.getErrorResponseCode() == ErrorResponse.ERROR_RESPONSE_CODE_BAD_NONCE) { - podState.resyncNonce(error.getNonceSearchKey(), message.getSentNonce(), message.getSequenceNumber()); + podStateManager.resyncNonce(error.getNonceSearchKey(), message.getSentNonce(), message.getSequenceNumber()); if (automaticallyResyncNonce) { - message.resyncNonce(podState.getCurrentNonce()); + message.resyncNonce(podStateManager.getCurrentNonce()); } else { throw new NonceOutOfSyncException(); } @@ -163,7 +160,7 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager { } } else if (responseMessageBlock.getType() == MessageBlockType.POD_INFO_RESPONSE && ((PodInfoResponse) responseMessageBlock).getSubType() == PodInfoType.FAULT_EVENT) { PodInfoFaultEvent faultEvent = ((PodInfoResponse) responseMessageBlock).getPodInfo(); - podState.setFaultEvent(faultEvent); + podStateManager.setFaultEvent(faultEvent); throw new PodFaultException(faultEvent); } else { throw new IllegalResponseException(responseClass.getSimpleName(), responseMessageBlock.getType()); @@ -174,13 +171,13 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager { throw new NonceResyncException(); } - private MessageBlock transportMessages(PodState podState, OmnipodMessage message, Integer addressOverride, Integer ackAddressOverride) { - int packetAddress = podState.getAddress(); + private MessageBlock transportMessages(PodStateManager podStateManager, OmnipodMessage message, Integer addressOverride, Integer ackAddressOverride) { + int packetAddress = podStateManager.getAddress(); if (addressOverride != null) { packetAddress = addressOverride; } - podState.increaseMessageNumber(); + podStateManager.increaseMessageNumber(); boolean firstPacket = true; byte[] encodedMessage; @@ -203,7 +200,7 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager { OmnipodPacket response = null; while (encodedMessage.length > 0) { PacketType packetType = firstPacket ? PacketType.PDM : PacketType.CON; - OmnipodPacket packet = new OmnipodPacket(packetAddress, packetType, podState.getPacketNumber(), encodedMessage); + OmnipodPacket packet = new OmnipodPacket(packetAddress, packetType, podStateManager.getPacketNumber(), encodedMessage); byte[] encodedMessageInPacket = packet.getEncodedMessage(); // getting the data remaining to be sent @@ -212,7 +209,7 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager { try { // We actually ignore previous (ack) responses if it was not last packet to send - response = exchangePackets(podState, packet); + response = exchangePackets(podStateManager, packet); } catch (Exception ex) { OmnipodException newException; if (ex instanceof OmnipodException) { @@ -245,15 +242,15 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager { if (receivedMessage.getAddress() != message.getAddress()) { throw new IllegalMessageAddressException(message.getAddress(), receivedMessage.getAddress()); } - if (receivedMessage.getSequenceNumber() != podState.getMessageNumber()) { - throw new IllegalMessageSequenceNumberException(podState.getMessageNumber(), receivedMessage.getSequenceNumber()); + if (receivedMessage.getSequenceNumber() != podStateManager.getMessageNumber()) { + throw new IllegalMessageSequenceNumberException(podStateManager.getMessageNumber(), receivedMessage.getSequenceNumber()); } } catch (NotEnoughDataException ex) { // Message is (probably) not complete yet - OmnipodPacket ackForCon = createAckPacket(podState, packetAddress, ackAddressOverride); + OmnipodPacket ackForCon = createAckPacket(podStateManager, packetAddress, ackAddressOverride); try { - OmnipodPacket conPacket = exchangePackets(podState, ackForCon, 3, 40); + OmnipodPacket conPacket = exchangePackets(podStateManager, ackForCon, 3, 40); if (conPacket.getPacketType() != PacketType.CON) { throw new IllegalPacketTypeException(PacketType.CON, conPacket.getPacketType()); } @@ -267,7 +264,7 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager { } } - ackUntilQuiet(podState, packetAddress, ackAddressOverride); + ackUntilQuiet(podStateManager, packetAddress, ackAddressOverride); List messageBlocks = receivedMessage.getMessageBlocks(); @@ -281,24 +278,24 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager { MessageBlock messageBlock = messageBlocks.get(0); if (messageBlock.getType() != MessageBlockType.ERROR_RESPONSE) { - podState.increaseMessageNumber(); + podStateManager.increaseMessageNumber(); } return messageBlock; } - private OmnipodPacket createAckPacket(PodState podState, Integer packetAddress, Integer messageAddress) { + private OmnipodPacket createAckPacket(PodStateManager podStateManager, Integer packetAddress, Integer messageAddress) { if (packetAddress == null) { - packetAddress = podState.getAddress(); + packetAddress = podStateManager.getAddress(); } if (messageAddress == null) { - messageAddress = podState.getAddress(); + messageAddress = podStateManager.getAddress(); } - return new OmnipodPacket(packetAddress, PacketType.ACK, podState.getPacketNumber(), ByteUtil.getBytesFromInt(messageAddress)); + return new OmnipodPacket(packetAddress, PacketType.ACK, podStateManager.getPacketNumber(), ByteUtil.getBytesFromInt(messageAddress)); } - private void ackUntilQuiet(PodState podState, Integer packetAddress, Integer messageAddress) { - OmnipodPacket ack = createAckPacket(podState, packetAddress, messageAddress); + private void ackUntilQuiet(PodStateManager podStateManager, Integer packetAddress, Integer messageAddress) { + OmnipodPacket ack = createAckPacket(podStateManager, packetAddress, messageAddress); boolean quiet = false; while (!quiet) try { sendAndListen(ack, 300, 1, 0, 40, OmnipodPacket.class); @@ -314,21 +311,21 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager { throw new CommunicationException(CommunicationException.Type.UNEXPECTED_EXCEPTION, ex); } - podState.increasePacketNumber(); + podStateManager.increasePacketNumber(); } - private OmnipodPacket exchangePackets(PodState podState, OmnipodPacket packet) { - return exchangePackets(podState, packet, 0, 333, 9000, 127); + private OmnipodPacket exchangePackets(PodStateManager podStateManager, OmnipodPacket packet) { + return exchangePackets(podStateManager, packet, 0, 333, 9000, 127); } - private OmnipodPacket exchangePackets(PodState podState, OmnipodPacket packet, int repeatCount, int preambleExtensionMilliseconds) { - return exchangePackets(podState, packet, repeatCount, 333, 9000, preambleExtensionMilliseconds); + private OmnipodPacket exchangePackets(PodStateManager podStateManager, OmnipodPacket packet, int repeatCount, int preambleExtensionMilliseconds) { + return exchangePackets(podStateManager, packet, repeatCount, 333, 9000, preambleExtensionMilliseconds); } - private OmnipodPacket exchangePackets(PodState podState, OmnipodPacket packet, int repeatCount, int responseTimeoutMilliseconds, int exchangeTimeoutMilliseconds, int preambleExtensionMilliseconds) { + private OmnipodPacket exchangePackets(PodStateManager podStateManager, OmnipodPacket packet, int repeatCount, int responseTimeoutMilliseconds, int exchangeTimeoutMilliseconds, int preambleExtensionMilliseconds) { long timeoutTime = System.currentTimeMillis() + exchangeTimeoutMilliseconds; - podState.increasePacketNumber(); + podStateManager.increasePacketNumber(); while (System.currentTimeMillis() < timeoutTime) { OmnipodPacket response = null; @@ -353,13 +350,13 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager { continue; } - if (response.getSequenceNumber() != podState.getPacketNumber()) { - aapsLogger.debug(LTag.PUMPBTCOMM, "Packet sequence number " + response.getSequenceNumber() + " does not match " + podState.getPacketNumber()); + if (response.getSequenceNumber() != podStateManager.getPacketNumber()) { + aapsLogger.debug(LTag.PUMPBTCOMM, "Packet sequence number " + response.getSequenceNumber() + " does not match " + podStateManager.getPacketNumber()); continue; } // Once we have verification that the POD heard us, we can increment our counters - podState.increasePacketNumber(); + podStateManager.increasePacketNumber(); return response; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodManager.java index c1a4cd57c5..6c12b27ab2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodManager.java @@ -5,7 +5,6 @@ import org.joda.time.DateTimeZone; import org.joda.time.Duration; import java.util.EnumSet; -import java.util.Random; import java.util.TimeZone; import java.util.concurrent.TimeUnit; @@ -40,8 +39,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.defs.DeliveryType; import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType; import info.nightscout.androidaps.plugins.pump.omnipod.defs.SetupProgress; import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BasalSchedule; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateChangedHandler; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; import info.nightscout.androidaps.utils.sharedPreferences.SP; @@ -55,49 +53,45 @@ import io.reactivex.subjects.SingleSubject; public class OmnipodManager { private static final int ACTION_VERIFICATION_TRIES = 3; - protected final OmnipodCommunicationManager communicationService; - private final PodStateChangedHandler podStateChangedHandler; - protected PodSessionState podState; + private final OmnipodCommunicationManager communicationService; + private PodStateManager podStateManager; private ActiveBolusData activeBolusData; private final Object bolusDataMutex = new Object(); private AAPSLogger aapsLogger; - private SP sp; public OmnipodManager(AAPSLogger aapsLogger, SP sp, OmnipodCommunicationManager communicationService, - PodSessionState podState, - PodStateChangedHandler podStateChangedHandler) { + PodStateManager podStateManager) { if (communicationService == null) { throw new IllegalArgumentException("Communication service cannot be null"); } - this.aapsLogger = aapsLogger; - this.sp = sp; - this.communicationService = communicationService; - if (podState != null) { - podState.setStateChangedHandler(podStateChangedHandler); + if (podStateManager == null) { + throw new IllegalArgumentException("Pod State Manager can not be null"); } - this.podState = podState; - this.podStateChangedHandler = podStateChangedHandler; + this.aapsLogger = aapsLogger; + this.communicationService = communicationService; + + this.podStateManager = podStateManager; } - public synchronized Single pairAndPrime(int address) { + public synchronized Single pairAndPrime() { logStartingCommandExecution("pairAndPrime"); try { - if (podState == null || podState.getSetupProgress().isBefore(SetupProgress.POD_CONFIGURED)) { + if (!podStateManager.hasState() || !podStateManager.getSetupProgress().isBefore(SetupProgress.POD_CONFIGURED)) { // Always send both 0x07 and 0x03 on retries - podState = communicationService.executeAction( - new AssignAddressAction(podStateChangedHandler, address)); + communicationService.executeAction( + new AssignAddressAction(podStateManager)); - communicationService.executeAction(new SetupPodAction(podState)); - } else if (SetupProgress.PRIMING.isBefore(podState.getSetupProgress())) { - throw new IllegalSetupProgressException(SetupProgress.POD_CONFIGURED, podState.getSetupProgress()); + communicationService.executeAction(new SetupPodAction(podStateManager)); + } else if (SetupProgress.PRIMING.isBefore(podStateManager.getSetupProgress())) { + throw new IllegalSetupProgressException(SetupProgress.POD_CONFIGURED, podStateManager.getSetupProgress()); } - communicationService.executeAction(new PrimeAction(new PrimeService(), podState)); + communicationService.executeAction(new PrimeAction(new PrimeService(), podStateManager)); } finally { logCommandExecutionFinished("pairAndPrime"); } @@ -106,21 +100,21 @@ public class OmnipodManager { return Single.timer(delayInSeconds, TimeUnit.SECONDS) // .map(o -> verifySetupAction(statusResponse -> - PrimeAction.updatePrimingStatus(podState, statusResponse, aapsLogger), SetupProgress.PRIMING_FINISHED)) // + PrimeAction.updatePrimingStatus(podStateManager, statusResponse, aapsLogger), SetupProgress.PRIMING_FINISHED)) // .observeOn(Schedulers.io()); } public synchronized Single insertCannula(BasalSchedule basalSchedule) { - if (podState == null || podState.getSetupProgress().isBefore(SetupProgress.PRIMING_FINISHED)) { - throw new IllegalSetupProgressException(SetupProgress.PRIMING_FINISHED, podState == null ? null : podState.getSetupProgress()); - } else if (podState.getSetupProgress().isAfter(SetupProgress.CANNULA_INSERTING)) { - throw new IllegalSetupProgressException(SetupProgress.CANNULA_INSERTING, podState.getSetupProgress()); + if (!podStateManager.hasState() || podStateManager.getSetupProgress().isBefore(SetupProgress.PRIMING_FINISHED)) { + throw new IllegalSetupProgressException(SetupProgress.PRIMING_FINISHED, !podStateManager.hasState() ? null : podStateManager.getSetupProgress()); + } else if (podStateManager.getSetupProgress().isAfter(SetupProgress.CANNULA_INSERTING)) { + throw new IllegalSetupProgressException(SetupProgress.CANNULA_INSERTING, podStateManager.getSetupProgress()); } logStartingCommandExecution("insertCannula [basalSchedule=" + basalSchedule + "]"); try { - communicationService.executeAction(new InsertCannulaAction(new InsertCannulaService(), podState, basalSchedule)); + communicationService.executeAction(new InsertCannulaAction(new InsertCannulaService(), podStateManager, basalSchedule)); } finally { logCommandExecutionFinished("insertCannula"); } @@ -129,19 +123,19 @@ public class OmnipodManager { return Single.timer(delayInSeconds, TimeUnit.SECONDS) // .map(o -> verifySetupAction(statusResponse -> - InsertCannulaAction.updateCannulaInsertionStatus(podState, statusResponse, aapsLogger), SetupProgress.COMPLETED)) // + InsertCannulaAction.updateCannulaInsertionStatus(podStateManager, statusResponse, aapsLogger), SetupProgress.COMPLETED)) // .observeOn(Schedulers.io()); } public synchronized StatusResponse getPodStatus() { - if (podState == null) { + if (!podStateManager.hasState()) { throw new IllegalSetupProgressException(SetupProgress.PRIMING_FINISHED, null); } logStartingCommandExecution("getPodStatus"); try { - return communicationService.executeAction(new GetStatusAction(podState)); + return communicationService.executeAction(new GetStatusAction(podStateManager)); } finally { logCommandExecutionFinished("getPodStatus"); } @@ -153,7 +147,7 @@ public class OmnipodManager { logStartingCommandExecution("getPodInfo"); try { - return communicationService.executeAction(new GetPodInfoAction(podState, podInfoType)); + return communicationService.executeAction(new GetPodInfoAction(podStateManager, podInfoType)); } finally { logCommandExecutionFinished("getPodInfo"); } @@ -165,7 +159,7 @@ public class OmnipodManager { logStartingCommandExecution("acknowledgeAlerts"); try { - return executeAndVerify(() -> communicationService.executeAction(new AcknowledgeAlertsAction(podState, podState.getActiveAlerts()))); + return executeAndVerify(() -> communicationService.executeAction(new AcknowledgeAlertsAction(podStateManager, podStateManager.getActiveAlerts()))); } finally { logCommandExecutionFinished("acknowledgeAlerts"); } @@ -187,8 +181,8 @@ public class OmnipodManager { try { try { - return executeAndVerify(() -> communicationService.executeAction(new SetBasalScheduleAction(podState, schedule, - false, podState.getScheduleOffset(), acknowledgementBeep))); + return executeAndVerify(() -> communicationService.executeAction(new SetBasalScheduleAction(podStateManager, schedule, + false, podStateManager.getScheduleOffset(), acknowledgementBeep))); } catch (OmnipodException ex) { // Treat all exceptions as uncertain failures, because all delivery has been suspended here. // Setting this to an uncertain failure will enable for the user to get an appropriate warning @@ -215,7 +209,7 @@ public class OmnipodManager { try { return executeAndVerify(() -> communicationService.executeAction(new SetTempBasalAction( - podState, rate, duration, + podStateManager, rate, duration, acknowledgementBeep, completionBeep))); } catch (OmnipodException ex) { // Treat all exceptions as uncertain failures, because all delivery has been suspended here. @@ -238,7 +232,7 @@ public class OmnipodManager { try { return executeAndVerify(() -> { - StatusResponse statusResponse = communicationService.executeAction(new CancelDeliveryAction(podState, deliveryTypes, acknowledgementBeep)); + StatusResponse statusResponse = communicationService.executeAction(new CancelDeliveryAction(podStateManager, deliveryTypes, acknowledgementBeep)); aapsLogger.info(LTag.PUMPBTCOMM, "Status response after cancel delivery[types={}]: {}", deliveryTypes.toString(), statusResponse.toString()); return statusResponse; }); @@ -258,7 +252,7 @@ public class OmnipodManager { CommandDeliveryStatus commandDeliveryStatus = CommandDeliveryStatus.SUCCESS; try { - executeAndVerify(() -> communicationService.executeAction(new BolusAction(podState, units, acknowledgementBeep, completionBeep))); + executeAndVerify(() -> communicationService.executeAction(new BolusAction(podStateManager, units, acknowledgementBeep, completionBeep))); } catch (OmnipodException ex) { if (ex.isCertainFailure()) { throw ex; @@ -339,7 +333,7 @@ public class OmnipodManager { synchronized (bolusDataMutex) { if (activeBolusData == null) { - throw new IllegalDeliveryStatusException(DeliveryStatus.BOLUS_IN_PROGRESS, podState.getLastDeliveryStatus()); + throw new IllegalDeliveryStatusException(DeliveryStatus.BOLUS_IN_PROGRESS, podStateManager.getLastDeliveryStatus()); } logStartingCommandExecution("cancelBolus [acknowledgementBeep=" + acknowledgementBeep + "]"); @@ -374,8 +368,8 @@ public class OmnipodManager { logStartingCommandExecution("resumeDelivery"); try { - return executeAndVerify(() -> communicationService.executeAction(new SetBasalScheduleAction(podState, podState.getBasalSchedule(), - false, podState.getScheduleOffset(), acknowledgementBeep))); + return executeAndVerify(() -> communicationService.executeAction(new SetBasalScheduleAction(podStateManager, podStateManager.getBasalSchedule(), + false, podStateManager.getScheduleOffset(), acknowledgementBeep))); } finally { logCommandExecutionFinished("resumeDelivery"); } @@ -395,18 +389,18 @@ public class OmnipodManager { throw ex; } - DateTimeZone oldTimeZone = podState.getTimeZone(); + DateTimeZone oldTimeZone = podStateManager.getTimeZone(); try { // Joda seems to cache the default time zone, so we use the JVM's DateTimeZone.setDefault(DateTimeZone.forTimeZone(TimeZone.getDefault())); - podState.setTimeZone(DateTimeZone.getDefault()); + podStateManager.setTimeZone(DateTimeZone.getDefault()); - setBasalSchedule(podState.getBasalSchedule(), acknowledgementBeeps); + setBasalSchedule(podStateManager.getBasalSchedule(), acknowledgementBeeps); } catch (OmnipodException ex) { // Treat all exceptions as uncertain failures, because all delivery has been suspended here. // Setting this to an uncertain failure will enable for the user to get an appropriate warning - podState.setTimeZone(oldTimeZone); + podStateManager.setTimeZone(oldTimeZone); ex.setCertainFailure(false); throw ex; } finally { @@ -415,7 +409,7 @@ public class OmnipodManager { } public synchronized void deactivatePod() { - if (podState == null) { + if (!podStateManager.isPaired()) { throw new IllegalSetupProgressException(SetupProgress.ADDRESS_ASSIGNED, null); } @@ -424,7 +418,7 @@ public class OmnipodManager { // Try to get pulse log for diagnostics // FIXME replace by storing to file try { - PodInfoResponse podInfoResponse = communicationService.executeAction(new GetPodInfoAction(podState, PodInfoType.RECENT_PULSE_LOG)); + PodInfoResponse podInfoResponse = communicationService.executeAction(new GetPodInfoAction(podStateManager, PodInfoType.RECENT_PULSE_LOG)); PodInfoRecentPulseLog pulseLogInfo = podInfoResponse.getPodInfo(); aapsLogger.info(LTag.PUMPBTCOMM, "Retrieved pulse log from the pod: {}", pulseLogInfo.toString()); } catch (Exception ex) { @@ -433,20 +427,14 @@ public class OmnipodManager { try { // Always send acknowledgement beeps here. Matches the PDM's behavior - communicationService.executeAction(new DeactivatePodAction(podState, true)); + communicationService.executeAction(new DeactivatePodAction(podStateManager, true)); } catch (PodFaultException ex) { aapsLogger.info(LTag.PUMPBTCOMM, "Ignoring PodFaultException in deactivatePod", ex); } finally { logCommandExecutionFinished("deactivatePod"); } - resetPodState(false); - } - - public void resetPodState(boolean forcedByUser) { - aapsLogger.warn(LTag.PUMPBTCOMM, "resetPodState has been called. forcedByUser={}", forcedByUser); - podState = null; - sp.remove(OmnipodConst.Prefs.PodState); + podStateManager.removeState(); } public OmnipodCommunicationManager getCommunicationService() { @@ -454,11 +442,11 @@ public class OmnipodManager { } public DateTime getTime() { - return podState.getTime(); + return podStateManager.getTime(); } public boolean isReadyForDelivery() { - return podState != null && podState.getSetupProgress() == SetupProgress.COMPLETED; + return podStateManager.isPaired() && podStateManager.getSetupProgress() == SetupProgress.COMPLETED; } public boolean hasActiveBolus() { @@ -467,13 +455,12 @@ public class OmnipodManager { } } - // FIXME this is dirty, we should not expose the original pod state - public PodSessionState getPodState() { - return this.podState; + public PodStateManager getPodStateManager() { + return this.podStateManager; } public String getPodStateAsString() { - return podState == null ? "null" : podState.toString(); + return podStateManager.hasState() ? podStateManager.toString() : "null"; } // Only works for commands with nonce resyncable message blocks @@ -489,8 +476,8 @@ public class OmnipodManager { try { logStartingCommandExecution("verifyCommand"); - StatusResponse statusResponse = communicationService.sendCommand(StatusResponse.class, podState, - new CancelDeliveryCommand(podState.getCurrentNonce(), BeepType.NO_BEEP, DeliveryType.NONE), false); + StatusResponse statusResponse = communicationService.sendCommand(StatusResponse.class, podStateManager, + new CancelDeliveryCommand(podStateManager.getCurrentNonce(), BeepType.NO_BEEP, DeliveryType.NONE), false); aapsLogger.info(LTag.PUMPBTCOMM, "Command status resolved to SUCCESS. Status response after cancelDelivery[types=DeliveryType.NONE]: {}", statusResponse); return statusResponse; @@ -517,7 +504,7 @@ public class OmnipodManager { private void assertReadyForDelivery() { if (!isReadyForDelivery()) { - throw new IllegalSetupProgressException(SetupProgress.COMPLETED, podState == null ? null : podState.getSetupProgress()); + throw new IllegalSetupProgressException(SetupProgress.COMPLETED, !podStateManager.hasState() ? null : podStateManager.getSetupProgress()); } } @@ -525,15 +512,15 @@ public class OmnipodManager { SetupActionResult result = null; for (int i = 0; ACTION_VERIFICATION_TRIES > i; i++) { try { - StatusResponse delayedStatusResponse = communicationService.executeAction(new GetStatusAction(podState)); + StatusResponse delayedStatusResponse = communicationService.executeAction(new GetStatusAction(podStateManager)); setupActionResponseHandler.accept(delayedStatusResponse); - if (podState.getSetupProgress().equals(expectedSetupProgress)) { + if (podStateManager.getSetupProgress().equals(expectedSetupProgress)) { result = new SetupActionResult(SetupActionResult.ResultType.SUCCESS); break; } else { result = new SetupActionResult(SetupActionResult.ResultType.FAILURE) // - .setupProgress(podState.getSetupProgress()); + .setupProgress(podStateManager.getSetupProgress()); break; } } catch (Exception ex) { @@ -564,15 +551,6 @@ public class OmnipodManager { return ex instanceof OmnipodException && ((OmnipodException) ex).isCertainFailure(); } - public static int generateRandomAddress() { - // Create random address with 20 bits to match PDM, could easily use 24 bits instead - return 0x1f000000 | (new Random().nextInt() & 0x000fffff); - } - - public static boolean isValidAddress(int address) { - return (0x1f000000 | (address & 0x000fffff)) == address; - } - public static class BolusCommandResult { private final CommandDeliveryStatus commandDeliveryStatus; private final SingleSubject deliveryResultSubject; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/AcknowledgeAlertsAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/AcknowledgeAlertsAction.java index facdb4b2d5..3ffbc5942f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/AcknowledgeAlertsAction.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/AcknowledgeAlertsAction.java @@ -3,37 +3,37 @@ package info.nightscout.androidaps.plugins.pump.omnipod.comm.action; import java.util.Collections; import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; +import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.AcknowledgeAlertsCommand; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSet; import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSlot; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; public class AcknowledgeAlertsAction implements OmnipodAction { - private final PodSessionState podState; + private final PodStateManager podStateManager; private final AlertSet alerts; - public AcknowledgeAlertsAction(PodSessionState podState, AlertSet alerts) { - if (podState == null) { - throw new ActionInitializationException("Pod state cannot be null"); + public AcknowledgeAlertsAction(PodStateManager podStateManager, AlertSet alerts) { + if (podStateManager == null) { + throw new ActionInitializationException("Pod state manager cannot be null"); } if (alerts == null) { throw new ActionInitializationException("Alert set can not be null"); } else if (alerts.size() == 0) { throw new ActionInitializationException("Alert set can not be empty"); } - this.podState = podState; + this.podStateManager = podStateManager; this.alerts = alerts; } - public AcknowledgeAlertsAction(PodSessionState podState, AlertSlot alertSlot) { - this(podState, new AlertSet(Collections.singletonList(alertSlot))); + public AcknowledgeAlertsAction(PodStateManager podStateManager, AlertSlot alertSlot) { + this(podStateManager, new AlertSet(Collections.singletonList(alertSlot))); } @Override public StatusResponse execute(OmnipodCommunicationManager communicationService) { - return communicationService.sendCommand(StatusResponse.class, podState, - new AcknowledgeAlertsCommand(podState.getCurrentNonce(), alerts)); + return communicationService.sendCommand(StatusResponse.class, podStateManager, + new AcknowledgeAlertsCommand(podStateManager.getCurrentNonce(), alerts)); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/AssignAddressAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/AssignAddressAction.java index b5e46e38b5..91590185e0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/AssignAddressAction.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/AssignAddressAction.java @@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.pump.omnipod.comm.action; import org.joda.time.DateTimeZone; import java.util.Collections; +import java.util.Random; import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalMessageAddressException; @@ -10,45 +11,52 @@ import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalVer import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.OmnipodMessage; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.AssignAddressCommand; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.VersionResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSetupState; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateChangedHandler; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; -public class AssignAddressAction implements OmnipodAction { - private final int address; - private final PodStateChangedHandler podStateChangedHandler; +public class AssignAddressAction implements OmnipodAction { + private final PodStateManager podStateManager; - public AssignAddressAction(PodStateChangedHandler podStateChangedHandler, int address) { - this.address = address; - this.podStateChangedHandler = podStateChangedHandler; + public AssignAddressAction(PodStateManager podStateManager) { + if (podStateManager == null) { + throw new IllegalArgumentException("podStateManager can not be null"); + } + this.podStateManager = podStateManager; } @Override - public PodSessionState execute(OmnipodCommunicationManager communicationService) { - PodSetupState setupState = new PodSetupState(address, 0x00, 0x00); + public VersionResponse execute(OmnipodCommunicationManager communicationService) { + if (!podStateManager.hasState()) { + podStateManager.initState(generateRandomAddress()); + } + if (podStateManager.isPaired()) { + throw new IllegalStateException("podStateManager already has a paired Pod"); + } - AssignAddressCommand assignAddress = new AssignAddressCommand(setupState.getAddress()); + AssignAddressCommand assignAddress = new AssignAddressCommand(podStateManager.getAddress()); OmnipodMessage assignAddressMessage = new OmnipodMessage(OmnipodConst.DEFAULT_ADDRESS, - Collections.singletonList(assignAddress), setupState.getMessageNumber()); + Collections.singletonList(assignAddress), podStateManager.getMessageNumber()); - VersionResponse assignAddressResponse = communicationService.exchangeMessages(VersionResponse.class, setupState, assignAddressMessage, - OmnipodConst.DEFAULT_ADDRESS, setupState.getAddress()); + VersionResponse assignAddressResponse = communicationService.exchangeMessages(VersionResponse.class, podStateManager, assignAddressMessage, + OmnipodConst.DEFAULT_ADDRESS, podStateManager.getAddress()); if (!assignAddressResponse.isAssignAddressVersionResponse()) { throw new IllegalVersionResponseTypeException("assignAddress", "setupPod"); } - if (assignAddressResponse.getAddress() != address) { - throw new IllegalMessageAddressException(address, assignAddressResponse.getAddress()); + if (assignAddressResponse.getAddress() != podStateManager.getAddress()) { + throw new IllegalMessageAddressException(podStateManager.getAddress(), assignAddressResponse.getAddress()); } - DateTimeZone timeZone = DateTimeZone.getDefault(); + podStateManager.setPairingParameters(assignAddressResponse.getLot(), assignAddressResponse.getTid(), // + assignAddressResponse.getPiVersion(), assignAddressResponse.getPmVersion(), DateTimeZone.getDefault()); + podStateManager.setMessageNumber(0x00); - PodSessionState podState = new PodSessionState(timeZone, address, assignAddressResponse.getPiVersion(), - assignAddressResponse.getPmVersion(), assignAddressResponse.getLot(), assignAddressResponse.getTid(), - setupState.getPacketNumber(), 0x00, communicationService.injector); // At this point, for an unknown reason, the pod starts counting messages from 0 again + return assignAddressResponse; + } - podState.setStateChangedHandler(podStateChangedHandler); - return podState; + + private static int generateRandomAddress() { + // Create random address with 20 bits to match PDM, could easily use 24 bits instead + return 0x1f000000 | (new Random().nextInt() & 0x000fffff); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/BolusAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/BolusAction.java index 14cee38962..c57d2b3615 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/BolusAction.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/BolusAction.java @@ -5,49 +5,49 @@ import org.joda.time.Duration; import java.util.Arrays; import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; +import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.OmnipodMessage; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.BolusExtraCommand; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.SetInsulinScheduleCommand; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BolusDeliverySchedule; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; public class BolusAction implements OmnipodAction { - private final PodSessionState podState; + private final PodStateManager podStateManager; private final double units; private final Duration timeBetweenPulses; private final boolean acknowledgementBeep; private final boolean completionBeep; - public BolusAction(PodSessionState podState, double units, Duration timeBetweenPulses, + public BolusAction(PodStateManager podStateManager, double units, Duration timeBetweenPulses, boolean acknowledgementBeep, boolean completionBeep) { - if (podState == null) { - throw new ActionInitializationException("Pod state cannot be null"); + if (podStateManager == null) { + throw new ActionInitializationException("Pod state manager cannot be null"); } if (timeBetweenPulses == null) { throw new ActionInitializationException("Time between pulses cannot be null"); } - this.podState = podState; + this.podStateManager = podStateManager; this.units = units; this.timeBetweenPulses = timeBetweenPulses; this.acknowledgementBeep = acknowledgementBeep; this.completionBeep = completionBeep; } - public BolusAction(PodSessionState podState, double units, boolean acknowledgementBeep, boolean completionBeep) { - this(podState, units, Duration.standardSeconds(2), acknowledgementBeep, completionBeep); + public BolusAction(PodStateManager podStateManager, double units, boolean acknowledgementBeep, boolean completionBeep) { + this(podStateManager, units, Duration.standardSeconds(2), acknowledgementBeep, completionBeep); } @Override public StatusResponse execute(OmnipodCommunicationManager communicationService) { BolusDeliverySchedule bolusDeliverySchedule = new BolusDeliverySchedule(units, timeBetweenPulses); SetInsulinScheduleCommand setInsulinScheduleCommand = new SetInsulinScheduleCommand( - podState.getCurrentNonce(), bolusDeliverySchedule); + podStateManager.getCurrentNonce(), bolusDeliverySchedule); BolusExtraCommand bolusExtraCommand = new BolusExtraCommand(units, timeBetweenPulses, acknowledgementBeep, completionBeep); - OmnipodMessage primeBolusMessage = new OmnipodMessage(podState.getAddress(), - Arrays.asList(setInsulinScheduleCommand, bolusExtraCommand), podState.getMessageNumber()); - return communicationService.exchangeMessages(StatusResponse.class, podState, primeBolusMessage); + OmnipodMessage primeBolusMessage = new OmnipodMessage(podStateManager.getAddress(), + Arrays.asList(setInsulinScheduleCommand, bolusExtraCommand), podStateManager.getMessageNumber()); + return communicationService.exchangeMessages(StatusResponse.class, podStateManager, primeBolusMessage); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/CancelDeliveryAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/CancelDeliveryAction.java index ca713bcab6..9df030fec5 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/CancelDeliveryAction.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/CancelDeliveryAction.java @@ -5,29 +5,29 @@ import java.util.EnumSet; import java.util.List; import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; +import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.MessageBlock; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.OmnipodMessage; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.CancelDeliveryCommand; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; import info.nightscout.androidaps.plugins.pump.omnipod.defs.BeepType; import info.nightscout.androidaps.plugins.pump.omnipod.defs.DeliveryType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; public class CancelDeliveryAction implements OmnipodAction { - private final PodSessionState podState; + private final PodStateManager podStateManager; private final EnumSet deliveryTypes; private final boolean acknowledgementBeep; - public CancelDeliveryAction(PodSessionState podState, EnumSet deliveryTypes, + public CancelDeliveryAction(PodStateManager podStateManager, EnumSet deliveryTypes, boolean acknowledgementBeep) { - if (podState == null) { - throw new ActionInitializationException("Pod state cannot be null"); + if (podStateManager == null) { + throw new ActionInitializationException("Pod state manager cannot be null"); } if (deliveryTypes == null) { throw new ActionInitializationException("Delivery types cannot be null"); } - this.podState = podState; + this.podStateManager = podStateManager; this.deliveryTypes = deliveryTypes; this.acknowledgementBeep = acknowledgementBeep; } @@ -43,14 +43,14 @@ public class CancelDeliveryAction implements OmnipodAction { EnumSet deliveryTypeWithBeep = EnumSet.of(deliveryTypeList.remove(deliveryTypeList.size() - 1)); EnumSet deliveryTypesWithoutBeep = EnumSet.copyOf(deliveryTypeList); - messageBlocks.add(new CancelDeliveryCommand(podState.getCurrentNonce(), BeepType.NO_BEEP, deliveryTypesWithoutBeep)); - messageBlocks.add(new CancelDeliveryCommand(podState.getCurrentNonce(), BeepType.BEEP, deliveryTypeWithBeep)); + messageBlocks.add(new CancelDeliveryCommand(podStateManager.getCurrentNonce(), BeepType.NO_BEEP, deliveryTypesWithoutBeep)); + messageBlocks.add(new CancelDeliveryCommand(podStateManager.getCurrentNonce(), BeepType.BEEP, deliveryTypeWithBeep)); } else { - messageBlocks.add(new CancelDeliveryCommand(podState.getCurrentNonce(), + messageBlocks.add(new CancelDeliveryCommand(podStateManager.getCurrentNonce(), acknowledgementBeep && deliveryTypes.size() == 1 ? BeepType.BEEP : BeepType.NO_BEEP, deliveryTypes)); } - return communicationService.exchangeMessages(StatusResponse.class, podState, - new OmnipodMessage(podState.getAddress(), messageBlocks, podState.getMessageNumber())); + return communicationService.exchangeMessages(StatusResponse.class, podStateManager, + new OmnipodMessage(podStateManager.getAddress(), messageBlocks, podStateManager.getMessageNumber())); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/ConfigureAlertsAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/ConfigureAlertsAction.java index b44fc092a8..e5f93e97f3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/ConfigureAlertsAction.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/ConfigureAlertsAction.java @@ -3,33 +3,33 @@ package info.nightscout.androidaps.plugins.pump.omnipod.comm.action; import java.util.List; import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; +import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.ConfigureAlertsCommand; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertConfiguration; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; public class ConfigureAlertsAction implements OmnipodAction { - private final PodSessionState podState; + private final PodStateManager podStateManager; private final List alertConfigurations; - public ConfigureAlertsAction(PodSessionState podState, List alertConfigurations) { - if (podState == null) { - throw new ActionInitializationException("Pod state cannot be null"); + public ConfigureAlertsAction(PodStateManager podStateManager, List alertConfigurations) { + if (podStateManager == null) { + throw new ActionInitializationException("Pod state manager cannot be null"); } if (alertConfigurations == null) { throw new ActionInitializationException("Alert configurations cannot be null"); } - this.podState = podState; + this.podStateManager = podStateManager; this.alertConfigurations = alertConfigurations; } @Override public StatusResponse execute(OmnipodCommunicationManager communicationService) { - ConfigureAlertsCommand configureAlertsCommand = new ConfigureAlertsCommand(podState.getCurrentNonce(), alertConfigurations); - StatusResponse statusResponse = communicationService.sendCommand(StatusResponse.class, podState, configureAlertsCommand); + ConfigureAlertsCommand configureAlertsCommand = new ConfigureAlertsCommand(podStateManager.getCurrentNonce(), alertConfigurations); + StatusResponse statusResponse = communicationService.sendCommand(StatusResponse.class, podStateManager, configureAlertsCommand); for (AlertConfiguration alertConfiguration : alertConfigurations) { - podState.putConfiguredAlert(alertConfiguration.getAlertSlot(), alertConfiguration.getAlertType()); + podStateManager.putConfiguredAlert(alertConfiguration.getAlertSlot(), alertConfiguration.getAlertType()); } return statusResponse; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/DeactivatePodAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/DeactivatePodAction.java index 01162ef434..7d1645c473 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/DeactivatePodAction.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/DeactivatePodAction.java @@ -3,36 +3,36 @@ package info.nightscout.androidaps.plugins.pump.omnipod.comm.action; import java.util.EnumSet; import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; +import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; +import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.PodFaultException; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.DeactivatePodCommand; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; import info.nightscout.androidaps.plugins.pump.omnipod.defs.DeliveryType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.PodFaultException; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; public class DeactivatePodAction implements OmnipodAction { - private final PodSessionState podState; + private final PodStateManager podStateManager; private final boolean acknowledgementBeep; - public DeactivatePodAction(PodSessionState podState, boolean acknowledgementBeep) { - if (podState == null) { - throw new ActionInitializationException("Pod state cannot be null"); + public DeactivatePodAction(PodStateManager podStateManager, boolean acknowledgementBeep) { + if (podStateManager == null) { + throw new ActionInitializationException("Pod state manager cannot be null"); } - this.podState = podState; + this.podStateManager = podStateManager; this.acknowledgementBeep = acknowledgementBeep; } @Override public StatusResponse execute(OmnipodCommunicationManager communicationService) { - if (!podState.isSuspended() && !podState.hasFaultEvent()) { + if (!podStateManager.isSuspended() && !podStateManager.hasFaultEvent()) { try { - communicationService.executeAction(new CancelDeliveryAction(podState, + communicationService.executeAction(new CancelDeliveryAction(podStateManager, EnumSet.allOf(DeliveryType.class), acknowledgementBeep)); - } catch(PodFaultException ex) { + } catch (PodFaultException ex) { // Ignore } } - return communicationService.sendCommand(StatusResponse.class, podState, new DeactivatePodCommand(podState.getCurrentNonce())); + return communicationService.sendCommand(StatusResponse.class, podStateManager, new DeactivatePodCommand(podStateManager.getCurrentNonce())); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/GetPodInfoAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/GetPodInfoAction.java index 0eef011607..a082ca47d8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/GetPodInfoAction.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/GetPodInfoAction.java @@ -1,29 +1,29 @@ package info.nightscout.androidaps.plugins.pump.omnipod.comm.action; import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; +import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.GetStatusCommand; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoResponse; import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; public class GetPodInfoAction implements OmnipodAction { - private final PodSessionState podState; + private final PodStateManager podStateManager; private final PodInfoType podInfoType; - public GetPodInfoAction(PodSessionState podState, PodInfoType podInfoType) { - if (podState == null) { - throw new ActionInitializationException("Pod state cannot be null"); + public GetPodInfoAction(PodStateManager podStateManager, PodInfoType podInfoType) { + if (podStateManager == null) { + throw new ActionInitializationException("Pod state manager cannot be null"); } if (podInfoType == null) { throw new ActionInitializationException("Pod info type cannot be null"); } - this.podState = podState; + this.podStateManager = podStateManager; this.podInfoType = podInfoType; } @Override public PodInfoResponse execute(OmnipodCommunicationManager communicationService) { - return communicationService.sendCommand(PodInfoResponse.class, podState, new GetStatusCommand(podInfoType)); + return communicationService.sendCommand(PodInfoResponse.class, podStateManager, new GetStatusCommand(podInfoType)); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/GetStatusAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/GetStatusAction.java index dfcc1fe043..35431cea8b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/GetStatusAction.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/GetStatusAction.java @@ -4,21 +4,21 @@ import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunication import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.GetStatusCommand; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; public class GetStatusAction implements OmnipodAction { - private final PodSessionState podState; + private final PodStateManager podStateManager; - public GetStatusAction(PodSessionState podState) { + public GetStatusAction(PodStateManager podState) { if (podState == null) { - throw new ActionInitializationException("Pod state cannot be null"); + throw new ActionInitializationException("Pod state manager cannot be null"); } - this.podState = podState; + this.podStateManager = podState; } @Override public StatusResponse execute(OmnipodCommunicationManager communicationService) { - return communicationService.sendCommand(StatusResponse.class, podState, new GetStatusCommand(PodInfoType.NORMAL)); + return communicationService.sendCommand(StatusResponse.class, podStateManager, new GetStatusCommand(PodInfoType.NORMAL)); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/InsertCannulaAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/InsertCannulaAction.java index 9a433ab86a..559b41e109 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/InsertCannulaAction.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/InsertCannulaAction.java @@ -9,63 +9,63 @@ import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalSet import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; import info.nightscout.androidaps.plugins.pump.omnipod.defs.SetupProgress; import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BasalSchedule; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; public class InsertCannulaAction implements OmnipodAction { - private final PodSessionState podState; + private final PodStateManager podStateManager; private final InsertCannulaService service; private final BasalSchedule initialBasalSchedule; - public InsertCannulaAction(InsertCannulaService insertCannulaService, PodSessionState podState, BasalSchedule initialBasalSchedule) { + public InsertCannulaAction(InsertCannulaService insertCannulaService, PodStateManager podStateManager, BasalSchedule initialBasalSchedule) { if (insertCannulaService == null) { throw new ActionInitializationException("Insert cannula service cannot be null"); } - if (podState == null) { - throw new ActionInitializationException("Pod state cannot be null"); + if (podStateManager == null) { + throw new ActionInitializationException("Pod state manager cannot be null"); } if (initialBasalSchedule == null) { throw new ActionInitializationException("Initial basal schedule cannot be null"); } this.service = insertCannulaService; - this.podState = podState; + this.podStateManager = podStateManager; this.initialBasalSchedule = initialBasalSchedule; } - public static void updateCannulaInsertionStatus(PodSessionState podState, StatusResponse statusResponse, AAPSLogger aapsLogger) { - if (podState.getSetupProgress().equals(SetupProgress.CANNULA_INSERTING) && + public static void updateCannulaInsertionStatus(PodStateManager podStateManager, StatusResponse statusResponse, AAPSLogger aapsLogger) { + if (podStateManager.getSetupProgress().equals(SetupProgress.CANNULA_INSERTING) && statusResponse.getPodProgressStatus().isReadyForDelivery()) { aapsLogger.debug(LTag.PUMPBTCOMM, "Updating SetupProgress from CANNULA_INSERTING to COMPLETED"); - podState.setSetupProgress(SetupProgress.COMPLETED); + podStateManager.setSetupProgress(SetupProgress.COMPLETED); } } @Override public StatusResponse execute(OmnipodCommunicationManager communicationService) { - if (podState.getSetupProgress().isBefore(SetupProgress.PRIMING_FINISHED)) { - throw new IllegalSetupProgressException(SetupProgress.PRIMING_FINISHED, podState.getSetupProgress()); + if (podStateManager.getSetupProgress().isBefore(SetupProgress.PRIMING_FINISHED)) { + throw new IllegalSetupProgressException(SetupProgress.PRIMING_FINISHED, podStateManager.getSetupProgress()); } - if (podState.getSetupProgress().isBefore(SetupProgress.INITIAL_BASAL_SCHEDULE_SET)) { - service.programInitialBasalSchedule(communicationService, podState, initialBasalSchedule); - podState.setSetupProgress(SetupProgress.INITIAL_BASAL_SCHEDULE_SET); + if (podStateManager.getSetupProgress().isBefore(SetupProgress.INITIAL_BASAL_SCHEDULE_SET)) { + service.programInitialBasalSchedule(communicationService, podStateManager, initialBasalSchedule); + podStateManager.setSetupProgress(SetupProgress.INITIAL_BASAL_SCHEDULE_SET); } - if (podState.getSetupProgress().isBefore(SetupProgress.STARTING_INSERT_CANNULA)) { - service.executeExpirationRemindersAlertCommand(communicationService, podState); - podState.setSetupProgress(SetupProgress.STARTING_INSERT_CANNULA); + if (podStateManager.getSetupProgress().isBefore(SetupProgress.STARTING_INSERT_CANNULA)) { + service.executeExpirationRemindersAlertCommand(communicationService, podStateManager); + podStateManager.setSetupProgress(SetupProgress.STARTING_INSERT_CANNULA); } - if (podState.getSetupProgress().isBefore(SetupProgress.CANNULA_INSERTING)) { - StatusResponse statusResponse = service.executeInsertionBolusCommand(communicationService, podState); - podState.setSetupProgress(SetupProgress.CANNULA_INSERTING); + if (podStateManager.getSetupProgress().isBefore(SetupProgress.CANNULA_INSERTING)) { + StatusResponse statusResponse = service.executeInsertionBolusCommand(communicationService, podStateManager); + podStateManager.setSetupProgress(SetupProgress.CANNULA_INSERTING); return statusResponse; - } else if (podState.getSetupProgress().equals(SetupProgress.CANNULA_INSERTING)) { + } else if (podStateManager.getSetupProgress().equals(SetupProgress.CANNULA_INSERTING)) { // Check status - StatusResponse statusResponse = communicationService.executeAction(new GetStatusAction(podState)); - updateCannulaInsertionStatus(podState, statusResponse, communicationService.aapsLogger); + StatusResponse statusResponse = communicationService.executeAction(new GetStatusAction(podStateManager)); + updateCannulaInsertionStatus(podStateManager, statusResponse, communicationService.aapsLogger); return statusResponse; } else { - throw new IllegalSetupProgressException(null, podState.getSetupProgress()); + throw new IllegalSetupProgressException(null, podStateManager.getSetupProgress()); } } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/PrimeAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/PrimeAction.java index 380eb0ce3d..a3056ac8a3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/PrimeAction.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/PrimeAction.java @@ -9,53 +9,53 @@ import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalSet import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodProgressStatus; import info.nightscout.androidaps.plugins.pump.omnipod.defs.SetupProgress; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; public class PrimeAction implements OmnipodAction { private final PrimeService service; - private final PodSessionState podState; + private final PodStateManager podStateManager; - public PrimeAction(PrimeService primeService, PodSessionState podState) { + public PrimeAction(PrimeService primeService, PodStateManager podStateManager) { if (primeService == null) { throw new ActionInitializationException("Prime service cannot be null"); } - if (podState == null) { - throw new ActionInitializationException("Pod state cannot be null"); + if (podStateManager == null) { + throw new ActionInitializationException("Pod state manager cannot be null"); } this.service = primeService; - this.podState = podState; + this.podStateManager = podStateManager; } - public static void updatePrimingStatus(PodSessionState podState, StatusResponse statusResponse, AAPSLogger aapsLogger) { - if (podState.getSetupProgress().equals(SetupProgress.PRIMING) && statusResponse.getPodProgressStatus().equals(PodProgressStatus.PRIMING_COMPLETED)) { + public static void updatePrimingStatus(PodStateManager podStateManager, StatusResponse statusResponse, AAPSLogger aapsLogger) { + if (podStateManager.getSetupProgress().equals(SetupProgress.PRIMING) && statusResponse.getPodProgressStatus().equals(PodProgressStatus.PRIMING_COMPLETED)) { aapsLogger.debug(LTag.PUMPBTCOMM, "Updating SetupProgress from PRIMING to PRIMING_FINISHED"); - podState.setSetupProgress(SetupProgress.PRIMING_FINISHED); + podStateManager.setSetupProgress(SetupProgress.PRIMING_FINISHED); } } @Override public StatusResponse execute(OmnipodCommunicationManager communicationService) { - if (podState.getSetupProgress().isBefore(SetupProgress.POD_CONFIGURED)) { - throw new IllegalSetupProgressException(SetupProgress.POD_CONFIGURED, podState.getSetupProgress()); + if (podStateManager.getSetupProgress().isBefore(SetupProgress.POD_CONFIGURED)) { + throw new IllegalSetupProgressException(SetupProgress.POD_CONFIGURED, podStateManager.getSetupProgress()); } - if (podState.getSetupProgress().isBefore(SetupProgress.STARTING_PRIME)) { - service.executeDisableTab5Sub16FaultConfigCommand(communicationService, podState); - service.executeFinishSetupReminderAlertCommand(communicationService, podState); - podState.setSetupProgress(SetupProgress.STARTING_PRIME); + if (podStateManager.getSetupProgress().isBefore(SetupProgress.STARTING_PRIME)) { + service.executeDisableTab5Sub16FaultConfigCommand(communicationService, podStateManager); + service.executeFinishSetupReminderAlertCommand(communicationService, podStateManager); + podStateManager.setSetupProgress(SetupProgress.STARTING_PRIME); } - if (podState.getSetupProgress().isBefore(SetupProgress.PRIMING)) { - StatusResponse statusResponse = service.executePrimeBolusCommand(communicationService, podState); - podState.setSetupProgress(SetupProgress.PRIMING); + if (podStateManager.getSetupProgress().isBefore(SetupProgress.PRIMING)) { + StatusResponse statusResponse = service.executePrimeBolusCommand(communicationService, podStateManager); + podStateManager.setSetupProgress(SetupProgress.PRIMING); return statusResponse; - } else if (podState.getSetupProgress().equals(SetupProgress.PRIMING)) { + } else if (podStateManager.getSetupProgress().equals(SetupProgress.PRIMING)) { // Check status - StatusResponse statusResponse = communicationService.executeAction(new GetStatusAction(podState)); - updatePrimingStatus(podState, statusResponse, communicationService.aapsLogger); + StatusResponse statusResponse = communicationService.executeAction(new GetStatusAction(podStateManager)); + updatePrimingStatus(podStateManager, statusResponse, communicationService.aapsLogger); return statusResponse; } else { - throw new IllegalSetupProgressException(null, podState.getSetupProgress()); + throw new IllegalSetupProgressException(null, podStateManager.getSetupProgress()); } } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetBasalScheduleAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetBasalScheduleAction.java index 0c8ae7f8be..1a4fd91237 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetBasalScheduleAction.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetBasalScheduleAction.java @@ -5,25 +5,25 @@ import org.joda.time.Duration; import java.util.Arrays; import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; +import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.OmnipodMessage; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.BasalScheduleExtraCommand; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.SetInsulinScheduleCommand; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BasalSchedule; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; public class SetBasalScheduleAction implements OmnipodAction { - private final PodSessionState podState; + private final PodStateManager podStateManager; private final BasalSchedule basalSchedule; private final boolean confidenceReminder; private final Duration scheduleOffset; private final boolean acknowledgementBeep; - public SetBasalScheduleAction(PodSessionState podState, BasalSchedule basalSchedule, + public SetBasalScheduleAction(PodStateManager podStateManager, BasalSchedule basalSchedule, boolean confidenceReminder, Duration scheduleOffset, boolean acknowledgementBeep) { - if (podState == null) { - throw new ActionInitializationException("Pod state cannot be null"); + if (podStateManager == null) { + throw new ActionInitializationException("Pod state manager cannot be null"); } if (basalSchedule == null) { throw new ActionInitializationException("Basal schedule cannot be null"); @@ -31,7 +31,7 @@ public class SetBasalScheduleAction implements OmnipodAction { if (scheduleOffset == null) { throw new ActionInitializationException("Schedule offset cannot be null"); } - this.podState = podState; + this.podStateManager = podStateManager; this.basalSchedule = basalSchedule; this.confidenceReminder = confidenceReminder; this.scheduleOffset = scheduleOffset; @@ -40,14 +40,14 @@ public class SetBasalScheduleAction implements OmnipodAction { @Override public StatusResponse execute(OmnipodCommunicationManager communicationService) { - SetInsulinScheduleCommand setBasal = new SetInsulinScheduleCommand(podState.getCurrentNonce(), basalSchedule, scheduleOffset); + SetInsulinScheduleCommand setBasal = new SetInsulinScheduleCommand(podStateManager.getCurrentNonce(), basalSchedule, scheduleOffset); BasalScheduleExtraCommand extraCommand = new BasalScheduleExtraCommand(basalSchedule, scheduleOffset, acknowledgementBeep, confidenceReminder, Duration.ZERO); - OmnipodMessage basalMessage = new OmnipodMessage(podState.getAddress(), Arrays.asList(setBasal, extraCommand), - podState.getMessageNumber()); + OmnipodMessage basalMessage = new OmnipodMessage(podStateManager.getAddress(), Arrays.asList(setBasal, extraCommand), + podStateManager.getMessageNumber()); - StatusResponse statusResponse = communicationService.exchangeMessages(StatusResponse.class, podState, basalMessage); - podState.setBasalSchedule(basalSchedule); + StatusResponse statusResponse = communicationService.exchangeMessages(StatusResponse.class, podStateManager, basalMessage); + podStateManager.setBasalSchedule(basalSchedule); return statusResponse; } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetTempBasalAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetTempBasalAction.java index d9406a3ed7..f316ece733 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetTempBasalAction.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetTempBasalAction.java @@ -6,30 +6,30 @@ import java.util.Arrays; import java.util.List; import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; +import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.MessageBlock; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.OmnipodMessage; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.SetInsulinScheduleCommand; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.TempBasalExtraCommand; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; public class SetTempBasalAction implements OmnipodAction { - private final PodSessionState podState; + private final PodStateManager podStateManager; private final double rate; private final Duration duration; private final boolean acknowledgementBeep; private final boolean completionBeep; - public SetTempBasalAction(PodSessionState podState, double rate, Duration duration, + public SetTempBasalAction(PodStateManager podStateManager, double rate, Duration duration, boolean acknowledgementBeep, boolean completionBeep) { - if (podState == null) { - throw new ActionInitializationException("Pod state cannot be null"); + if (podStateManager == null) { + throw new ActionInitializationException("Pod state manager cannot be null"); } if (duration == null) { throw new ActionInitializationException("Duration cannot be null"); } - this.podState = podState; + this.podStateManager = podStateManager; this.rate = rate; this.duration = duration; this.acknowledgementBeep = acknowledgementBeep; @@ -39,10 +39,10 @@ public class SetTempBasalAction implements OmnipodAction { @Override public StatusResponse execute(OmnipodCommunicationManager communicationService) { List messageBlocks = Arrays.asList( // - new SetInsulinScheduleCommand(podState.getCurrentNonce(), rate, duration), + new SetInsulinScheduleCommand(podStateManager.getCurrentNonce(), rate, duration), new TempBasalExtraCommand(rate, duration, acknowledgementBeep, completionBeep, Duration.ZERO)); - OmnipodMessage message = new OmnipodMessage(podState.getAddress(), messageBlocks, podState.getMessageNumber()); - return communicationService.exchangeMessages(StatusResponse.class, podState, message); + OmnipodMessage message = new OmnipodMessage(podStateManager.getAddress(), messageBlocks, podStateManager.getMessageNumber()); + return communicationService.exchangeMessages(StatusResponse.class, podStateManager, message); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetupPodAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetupPodAction.java index 52979c91f3..a2ef13e488 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetupPodAction.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetupPodAction.java @@ -16,35 +16,38 @@ import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.Ver import info.nightscout.androidaps.plugins.pump.omnipod.defs.PacketType; import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodProgressStatus; import info.nightscout.androidaps.plugins.pump.omnipod.defs.SetupProgress; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; public class SetupPodAction implements OmnipodAction { - private final PodSessionState podState; + private final PodStateManager podStateManager; - public SetupPodAction(PodSessionState podState) { - this.podState = podState; + public SetupPodAction(PodStateManager podStateManager) { + if(podStateManager == null) { + throw new IllegalArgumentException("Pod state manager can not be null"); + } + this.podStateManager = podStateManager; } @Override public VersionResponse execute(OmnipodCommunicationManager communicationService) { - if (!podState.getSetupProgress().equals(SetupProgress.ADDRESS_ASSIGNED)) { - throw new IllegalSetupProgressException(SetupProgress.ADDRESS_ASSIGNED, podState.getSetupProgress()); + if (!podStateManager.getSetupProgress().equals(SetupProgress.ADDRESS_ASSIGNED)) { + throw new IllegalSetupProgressException(SetupProgress.ADDRESS_ASSIGNED, podStateManager.getSetupProgress()); } - DateTime activationDate = DateTime.now(podState.getTimeZone()); + DateTime activationDate = DateTime.now(podStateManager.getTimeZone()); - SetupPodCommand setupPodCommand = new SetupPodCommand(podState.getAddress(), activationDate, - podState.getLot(), podState.getTid()); + SetupPodCommand setupPodCommand = new SetupPodCommand(podStateManager.getAddress(), activationDate, + podStateManager.getLot(), podStateManager.getTid()); OmnipodMessage message = new OmnipodMessage(OmnipodConst.DEFAULT_ADDRESS, - Collections.singletonList(setupPodCommand), podState.getMessageNumber()); + Collections.singletonList(setupPodCommand), podStateManager.getMessageNumber()); VersionResponse setupPodResponse; try { - setupPodResponse = communicationService.exchangeMessages(VersionResponse.class, podState, - message, OmnipodConst.DEFAULT_ADDRESS, podState.getAddress()); + setupPodResponse = communicationService.exchangeMessages(VersionResponse.class, podStateManager, + message, OmnipodConst.DEFAULT_ADDRESS, podStateManager.getAddress()); } catch (IllegalPacketTypeException ex) { if (PacketType.ACK.equals(ex.getActual())) { // Pod is already configured - podState.setSetupProgress(SetupProgress.POD_CONFIGURED); + podStateManager.setSetupProgress(SetupProgress.POD_CONFIGURED); return null; } throw ex; @@ -53,14 +56,14 @@ public class SetupPodAction implements OmnipodAction { if (!setupPodResponse.isSetupPodVersionResponse()) { throw new IllegalVersionResponseTypeException("setupPod", "assignAddress"); } - if (setupPodResponse.getAddress() != podState.getAddress()) { - throw new IllegalMessageAddressException(podState.getAddress(), setupPodResponse.getAddress()); + if (setupPodResponse.getAddress() != podStateManager.getAddress()) { + throw new IllegalMessageAddressException(podStateManager.getAddress(), setupPodResponse.getAddress()); } if (setupPodResponse.getPodProgressStatus() != PodProgressStatus.PAIRING_COMPLETED) { throw new IllegalPodProgressException(PodProgressStatus.PAIRING_COMPLETED, setupPodResponse.getPodProgressStatus()); } - podState.setSetupProgress(SetupProgress.POD_CONFIGURED); + podStateManager.setSetupProgress(SetupProgress.POD_CONFIGURED); return setupPodResponse; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/service/InsertCannulaService.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/service/InsertCannulaService.java index b897e448c8..61c786eeca 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/service/InsertCannulaService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/service/InsertCannulaService.java @@ -14,21 +14,21 @@ import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.Sta import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertConfiguration; import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertConfigurationFactory; import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BasalSchedule; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; public class InsertCannulaService { public StatusResponse programInitialBasalSchedule(OmnipodCommunicationManager communicationService, - PodSessionState podState, BasalSchedule basalSchedule) { - return communicationService.executeAction(new SetBasalScheduleAction(podState, basalSchedule, - true, podState.getScheduleOffset(), false)); + PodStateManager podStateManager, BasalSchedule basalSchedule) { + return communicationService.executeAction(new SetBasalScheduleAction(podStateManager, basalSchedule, + true, podStateManager.getScheduleOffset(), false)); } public StatusResponse executeExpirationRemindersAlertCommand(OmnipodCommunicationManager communicationService, - PodSessionState podState) { + PodStateManager podStateManager) { AlertConfiguration lowReservoirAlertConfiguration = AlertConfigurationFactory.createLowReservoirAlertConfiguration(OmnipodConst.LOW_RESERVOIR_ALERT); - DateTime endOfServiceTime = podState.getActivatedAt().plus(OmnipodConst.SERVICE_DURATION); + DateTime endOfServiceTime = podStateManager.getActivatedAt().plus(OmnipodConst.SERVICE_DURATION); Duration timeUntilExpirationAdvisoryAlarm = new Duration(DateTime.now(), endOfServiceTime.minus(OmnipodConst.EXPIRATION_ADVISORY_WINDOW)); @@ -49,11 +49,11 @@ public class InsertCannulaService { autoOffAlertConfiguration // ); - return new ConfigureAlertsAction(podState, alertConfigurations).execute(communicationService); + return new ConfigureAlertsAction(podStateManager, alertConfigurations).execute(communicationService); } - public StatusResponse executeInsertionBolusCommand(OmnipodCommunicationManager communicationService, PodSessionState podState) { - return communicationService.executeAction(new BolusAction(podState, OmnipodConst.POD_CANNULA_INSERTION_BOLUS_UNITS, + public StatusResponse executeInsertionBolusCommand(OmnipodCommunicationManager communicationService, PodStateManager podStateManager) { + return communicationService.executeAction(new BolusAction(podStateManager, OmnipodConst.POD_CANNULA_INSERTION_BOLUS_UNITS, Duration.standardSeconds(1), false, false)); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/service/PrimeService.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/service/PrimeService.java index 3fc7663398..d8726be029 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/service/PrimeService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/service/PrimeService.java @@ -12,26 +12,26 @@ import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.Faul import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertConfiguration; import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertConfigurationFactory; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; public class PrimeService { - public StatusResponse executeDisableTab5Sub16FaultConfigCommand(OmnipodCommunicationManager communicationService, PodSessionState podState) { - FaultConfigCommand faultConfigCommand = new FaultConfigCommand(podState.getCurrentNonce(), (byte) 0x00, (byte) 0x00); - OmnipodMessage faultConfigMessage = new OmnipodMessage(podState.getAddress(), - Collections.singletonList(faultConfigCommand), podState.getMessageNumber()); - return communicationService.exchangeMessages(StatusResponse.class, podState, faultConfigMessage); + public StatusResponse executeDisableTab5Sub16FaultConfigCommand(OmnipodCommunicationManager communicationService, PodStateManager podStateManager) { + FaultConfigCommand faultConfigCommand = new FaultConfigCommand(podStateManager.getCurrentNonce(), (byte) 0x00, (byte) 0x00); + OmnipodMessage faultConfigMessage = new OmnipodMessage(podStateManager.getAddress(), + Collections.singletonList(faultConfigCommand), podStateManager.getMessageNumber()); + return communicationService.exchangeMessages(StatusResponse.class, podStateManager, faultConfigMessage); } - public StatusResponse executeFinishSetupReminderAlertCommand(OmnipodCommunicationManager communicationService, PodSessionState podState) { + public StatusResponse executeFinishSetupReminderAlertCommand(OmnipodCommunicationManager communicationService, PodStateManager podStateManager) { AlertConfiguration finishSetupReminderAlertConfiguration = AlertConfigurationFactory.createFinishSetupReminderAlertConfiguration(); - return communicationService.executeAction(new ConfigureAlertsAction(podState, + return communicationService.executeAction(new ConfigureAlertsAction(podStateManager, Collections.singletonList(finishSetupReminderAlertConfiguration))); } - public StatusResponse executePrimeBolusCommand(OmnipodCommunicationManager communicationService, PodSessionState podState) { - return communicationService.executeAction(new BolusAction(podState, OmnipodConst.POD_PRIME_BOLUS_UNITS, + public StatusResponse executePrimeBolusCommand(OmnipodCommunicationManager communicationService, PodStateManager podStateManager) { + return communicationService.executeAction(new BolusAction(podStateManager, OmnipodConst.POD_PRIME_BOLUS_UNITS, Duration.standardSeconds(1), false, false)); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodSessionState.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodSessionState.java deleted file mode 100644 index 64cb92e84b..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodSessionState.java +++ /dev/null @@ -1,299 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs.state; - -import com.google.gson.Gson; - -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.Duration; - -import java.util.HashMap; -import java.util.Map; - -import javax.inject.Inject; - -import dagger.android.HasAndroidInjector; -import info.nightscout.androidaps.logging.AAPSLogger; -import info.nightscout.androidaps.logging.LTag; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoFaultEvent; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSet; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSlot; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.DeliveryStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.FirmwareVersion; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.NonceState; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.SetupProgress; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BasalSchedule; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmniCRC; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil; -import info.nightscout.androidaps.utils.DateUtil; -import info.nightscout.androidaps.utils.sharedPreferences.SP; - - -public class PodSessionState extends PodState { - - @Inject transient AAPSLogger aapsLogger; - @Inject transient SP sp; - @Inject transient OmnipodUtil omnipodUtil; - - private transient PodStateChangedHandler stateChangedHandler; - - private final Map configuredAlerts; - private DateTimeZone timeZone; - private DateTime activatedAt; - private DateTime expiresAt; - private final FirmwareVersion piVersion; - private final FirmwareVersion pmVersion; - private final int lot; - private final int tid; - private Double reservoirLevel; - private boolean suspended; - private NonceState nonceState; - private SetupProgress setupProgress; - private AlertSet activeAlerts; - private BasalSchedule basalSchedule; - private DeliveryStatus lastDeliveryStatus; - - public PodSessionState(DateTimeZone timeZone, int address, FirmwareVersion piVersion, - FirmwareVersion pmVersion, int lot, int tid, int packetNumber, int messageNumber, HasAndroidInjector injector) { - super(address, messageNumber, packetNumber); - injectDaggerClass(injector); - if (timeZone == null) { - throw new IllegalArgumentException("Time zone can not be null"); - } - - suspended = false; - configuredAlerts = new HashMap<>(); - configuredAlerts.put(AlertSlot.SLOT7, AlertType.FINISH_SETUP_REMINDER); - - this.timeZone = timeZone; - this.setupProgress = SetupProgress.ADDRESS_ASSIGNED; - this.piVersion = piVersion; - this.pmVersion = pmVersion; - this.lot = lot; - this.tid = tid; - this.nonceState = new NonceState(lot, tid); - handleUpdates(); - } - - public void injectDaggerClass(HasAndroidInjector injector) { - injector.androidInjector().inject(this); - } - - public void setStateChangedHandler(PodStateChangedHandler handler) { - // FIXME this is an ugly workaround for not being able to serialize the PodStateChangedHandler - if (stateChangedHandler != null) { - throw new IllegalStateException("A PodStateChangedHandler has already been already registered"); - } - stateChangedHandler = handler; - } - - public AlertType getConfiguredAlertType(AlertSlot alertSlot) { - return configuredAlerts.get(alertSlot); - } - - public void putConfiguredAlert(AlertSlot alertSlot, AlertType alertType) { - configuredAlerts.put(alertSlot, alertType); - handleUpdates(); - } - - public void removeConfiguredAlert(AlertSlot alertSlot) { - configuredAlerts.remove(alertSlot); - handleUpdates(); - } - - public DateTime getActivatedAt() { - return activatedAt == null ? null : activatedAt.withZone(timeZone); - } - - public DateTime getExpiresAt() { - return expiresAt == null ? null : expiresAt.withZone(timeZone); - } - - public String getExpiryDateAsString() { - return expiresAt == null ? "???" : DateUtil.dateAndTimeString(expiresAt.toDate()); - } - - public FirmwareVersion getPiVersion() { - return piVersion; - } - - public FirmwareVersion getPmVersion() { - return pmVersion; - } - - public int getLot() { - return lot; - } - - public int getTid() { - return tid; - } - - public Double getReservoirLevel() { - return reservoirLevel; - } - - public synchronized void resyncNonce(int syncWord, int sentNonce, int sequenceNumber) { - int sum = (sentNonce & 0xFFFF) - + OmniCRC.crc16lookup[sequenceNumber] - + (this.lot & 0xFFFF) - + (this.tid & 0xFFFF); - int seed = ((sum & 0xFFFF) ^ syncWord); - - this.nonceState = new NonceState(lot, tid, (byte) (seed & 0xFF)); - handleUpdates(); - } - - public int getCurrentNonce() { - return nonceState.getCurrentNonce(); - } - - public synchronized void advanceToNextNonce() { - nonceState.advanceToNextNonce(); - handleUpdates(); - } - - public SetupProgress getSetupProgress() { - return setupProgress; - } - - public synchronized void setSetupProgress(SetupProgress setupProgress) { - if (setupProgress == null) { - throw new IllegalArgumentException("Setup state cannot be null"); - } - this.setupProgress = setupProgress; - handleUpdates(); - } - - public boolean isSuspended() { - return suspended; - } - - public boolean hasActiveAlerts() { - return activeAlerts != null && activeAlerts.size() > 0; - } - - public AlertSet getActiveAlerts() { - return activeAlerts; - } - - public DateTimeZone getTimeZone() { - return timeZone; - } - - public void setTimeZone(DateTimeZone timeZone) { - if (timeZone == null) { - throw new IllegalArgumentException("Time zone can not be null"); - } - this.timeZone = timeZone; - handleUpdates(); - } - - public DateTime getTime() { - DateTime now = DateTime.now(); - return now.withZone(timeZone); - } - - public Duration getScheduleOffset() { - DateTime now = getTime(); - DateTime startOfDay = new DateTime(now.getYear(), now.getMonthOfYear(), now.getDayOfMonth(), - 0, 0, 0, timeZone); - return new Duration(startOfDay, now); - } - - public boolean hasNonceState() { - return true; - } - - @Override - public void setPacketNumber(int packetNumber) { - super.setPacketNumber(packetNumber); - handleUpdates(); - } - - @Override - public void setMessageNumber(int messageNumber) { - super.setMessageNumber(messageNumber); - handleUpdates(); - } - - public BasalSchedule getBasalSchedule() { - return basalSchedule; - } - - public void setBasalSchedule(BasalSchedule basalSchedule) { - this.basalSchedule = basalSchedule; - handleUpdates(); - } - - public DeliveryStatus getLastDeliveryStatus() { - return lastDeliveryStatus; - } - - @Override - public void setFaultEvent(PodInfoFaultEvent faultEvent) { - super.setFaultEvent(faultEvent); - suspended = true; - handleUpdates(); - } - - @Override - public void updateFromStatusResponse(StatusResponse statusResponse) { - DateTime activatedAtCalculated = getTime().minus(statusResponse.getTimeActive()); - if (activatedAt == null) { - activatedAt = activatedAtCalculated; - } - DateTime expiresAtCalculated = activatedAtCalculated.plus(OmnipodConst.NOMINAL_POD_LIFE); - if (expiresAt == null || expiresAtCalculated.isBefore(expiresAt) || expiresAtCalculated.isAfter(expiresAt.plusMinutes(1))) { - expiresAt = expiresAtCalculated; - } - - boolean newSuspendedState = statusResponse.getDeliveryStatus() == DeliveryStatus.SUSPENDED; - if (suspended != newSuspendedState) { - aapsLogger.info(LTag.PUMPCOMM, "Updating pod suspended state in updateFromStatusResponse. newSuspendedState={}, statusResponse={}", newSuspendedState, statusResponse.toString()); - suspended = newSuspendedState; - } - activeAlerts = statusResponse.getAlerts(); - lastDeliveryStatus = statusResponse.getDeliveryStatus(); - reservoirLevel = statusResponse.getReservoirLevel(); - handleUpdates(); - } - - private void handleUpdates() { - Gson gson = omnipodUtil.getGsonInstance(); - String gsonValue = gson.toJson(this); - aapsLogger.info(LTag.PUMPCOMM, "PodSessionState-SP: Saved Session State to SharedPreferences: " + gsonValue); - sp.putString(OmnipodConst.Prefs.PodState, gsonValue); - if (stateChangedHandler != null) { - stateChangedHandler.handle(this); - } - } - - @Override - public String toString() { - return "PodSessionState{" + - "configuredAlerts=" + configuredAlerts + - ", stateChangedHandler=" + stateChangedHandler + - ", activatedAt=" + activatedAt + - ", expiresAt=" + expiresAt + - ", piVersion=" + piVersion + - ", pmVersion=" + pmVersion + - ", lot=" + lot + - ", tid=" + tid + - ", reservoirLevel=" + reservoirLevel + - ", suspended=" + suspended + - ", timeZone=" + timeZone + - ", nonceState=" + nonceState + - ", setupProgress=" + setupProgress + - ", activeAlerts=" + activeAlerts + - ", basalSchedule=" + basalSchedule + - ", lastDeliveryStatus=" + lastDeliveryStatus + - ", address=" + address + - ", packetNumber=" + packetNumber + - ", messageNumber=" + messageNumber + - ", faultEvent=" + faultEvent + - '}'; - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodSetupState.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodSetupState.java deleted file mode 100644 index 26b5802258..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodSetupState.java +++ /dev/null @@ -1,43 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs.state; - -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; - -public class PodSetupState extends PodState { - public PodSetupState(int address, int packetNumber, int messageNumber) { - super(address, packetNumber, messageNumber); - } - - @Override - public boolean hasNonceState() { - return false; - } - - @Override - public int getCurrentNonce() { - throw new UnsupportedOperationException("PodSetupState does not have a nonce state"); - } - - @Override - public void advanceToNextNonce() { - throw new UnsupportedOperationException("PodSetupState does not have a nonce state"); - } - - @Override - public void resyncNonce(int syncWord, int sentNonce, int sequenceNumber) { - throw new UnsupportedOperationException("PodSetupState does not have a nonce state"); - } - - @Override - public void updateFromStatusResponse(StatusResponse statusResponse) { - } - - @Override - public String toString() { - return "PodSetupState{" + - "address=" + address + - ", packetNumber=" + packetNumber + - ", messageNumber=" + messageNumber + - ", faultEvent=" + faultEvent + - '}'; - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodState.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodState.java deleted file mode 100644 index c6987c879e..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodState.java +++ /dev/null @@ -1,68 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs.state; - -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoFaultEvent; - -public abstract class PodState { - protected final int address; - protected int packetNumber; - protected int messageNumber; - - protected PodInfoFaultEvent faultEvent; - - public PodState(int address, int packetNumber, int messageNumber) { - this.address = address; - this.packetNumber = packetNumber; - this.messageNumber = messageNumber; - } - - public abstract boolean hasNonceState(); - - public abstract int getCurrentNonce(); - - public abstract void advanceToNextNonce(); - - public abstract void resyncNonce(int syncWord, int sentNonce, int sequenceNumber); - - public abstract void updateFromStatusResponse(StatusResponse statusResponse); - - public int getAddress() { - return address; - } - - public int getMessageNumber() { - return messageNumber; - } - - public void setMessageNumber(int messageNumber) { - this.messageNumber = messageNumber; - } - - public int getPacketNumber() { - return packetNumber; - } - - public void setPacketNumber(int packetNumber) { - this.packetNumber = packetNumber; - } - - public void increaseMessageNumber() { - setMessageNumber((messageNumber + 1) & 0b1111); - } - - public void increasePacketNumber() { - setPacketNumber((packetNumber + 1) & 0b11111); - } - - public boolean hasFaultEvent() { - return faultEvent != null; - } - - public PodInfoFaultEvent getFaultEvent() { - return faultEvent; - } - - public void setFaultEvent(PodInfoFaultEvent faultEvent) { - this.faultEvent = faultEvent; - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateChangedHandler.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateChangedHandler.java index 6e706131a2..c1171b498e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateChangedHandler.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateChangedHandler.java @@ -2,5 +2,5 @@ package info.nightscout.androidaps.plugins.pump.omnipod.defs.state; @FunctionalInterface public interface PodStateChangedHandler { - void handle(PodSessionState podState); + void handle(PodStateManager podStateManager); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateManager.java index e9b0149835..009503bad1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateManager.java @@ -20,21 +20,25 @@ public interface PodStateManager { void removeState(); + void initState(int address); + boolean isPaired(); - public int getAddress(); + void setPairingParameters(int lot, int tid, FirmwareVersion piVersion, FirmwareVersion pmVersion, DateTimeZone timeZone); - public int getMessageNumber(); + int getAddress(); - public void setMessageNumber(int messageNumber); + int getMessageNumber(); - public int getPacketNumber(); + void setMessageNumber(int messageNumber); - public void setPacketNumber(int packetNumber); + int getPacketNumber(); - public void increaseMessageNumber(); + void setPacketNumber(int packetNumber); - public void increasePacketNumber(); + void increaseMessageNumber(); + + void increasePacketNumber(); void resyncNonce(int syncWord, int sentNonce, int sequenceNumber); @@ -42,11 +46,11 @@ public interface PodStateManager { void advanceToNextNonce(); - public boolean hasFaultEvent(); + boolean hasFaultEvent(); - public PodInfoFaultEvent getFaultEvent(); + PodInfoFaultEvent getFaultEvent(); - public void setFaultEvent(PodInfoFaultEvent faultEvent); + void setFaultEvent(PodInfoFaultEvent faultEvent); AlertType getConfiguredAlertType(AlertSlot alertSlot); @@ -95,4 +99,6 @@ public interface PodStateManager { DeliveryStatus getLastDeliveryStatus(); void updateFromStatusResponse(StatusResponse statusResponse); + + void setStateChangedHandler(PodStateChangedHandler handler); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/PodManagementActivity.kt b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/PodManagementActivity.kt index 372304ab66..c37a2af49f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/PodManagementActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/PodManagementActivity.kt @@ -45,7 +45,6 @@ class PodManagementActivity : NoSplashAppCompatActivity() { @Inject lateinit var injector: HasAndroidInjector private var initPodChanged = false - private var podSessionFullyInitalized = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -99,8 +98,8 @@ class PodManagementActivity : NoSplashAppCompatActivity() { wizardPagerContext.clearContext() wizardPagerContext.pagerSettings = pagerSettings - val podSessionState = omnipodUtil.getPodSessionState() - val isFullInit = podSessionState == null || podSessionState.setupProgress.isBefore(SetupProgress.PRIMING_FINISHED) + val podStateManager = omnipodUtil.getPodStateManager() + val isFullInit = podStateManager == null || podStateManager.setupProgress.isBefore(SetupProgress.PRIMING_FINISHED) if (isFullInit) { wizardPagerContext.wizardModel = FullInitPodWizardModel(applicationContext) } else { @@ -151,13 +150,13 @@ class PodManagementActivity : NoSplashAppCompatActivity() { } fun refreshButtons() { - initpod_init_pod.isEnabled = (omnipodUtil.getPodSessionState() == null || - omnipodUtil.getPodSessionState().getSetupProgress().isBefore(SetupProgress.COMPLETED)) + initpod_init_pod.isEnabled = omnipodUtil.podStateManager == null || !omnipodUtil.podStateManager.isPaired() || + omnipodUtil.getPodStateManager().getSetupProgress().isBefore(SetupProgress.COMPLETED) - val isPodSessionActive = (omnipodUtil.getPodSessionState() != null) + val isPodSessionActive = omnipodUtil.podStateManager != null && omnipodUtil.podStateManager.hasState() - initpod_remove_pod.isEnabled = isPodSessionActive - initpod_reset_pod.isEnabled = isPodSessionActive || omnipodUtil.hasNextPodAddress() + initpod_remove_pod.isEnabled = isPodSessionActive && omnipodUtil.podStateManager.isPaired + initpod_reset_pod.isEnabled = isPodSessionActive if (omnipodUtil.getDriverState() == OmnipodDriverState.NotInitalized) { // if rileylink is not running we disable all operations diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/pages/InitPodRefreshAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/pages/InitPodRefreshAction.java index 37c6d420f7..d6b9734233 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/pages/InitPodRefreshAction.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/pages/InitPodRefreshAction.java @@ -58,7 +58,7 @@ public class InitPodRefreshAction extends AbstractCancelAction implements Finish @Override public void execute() { if (actionType == PodActionType.InitPod) { - if (omnipodUtil.getPodSessionState().getSetupProgress().isBefore(SetupProgress.COMPLETED)) { + if (omnipodUtil.getPodStateManager().getSetupProgress().isBefore(SetupProgress.COMPLETED)) { omnipodUtil.setDriverState(OmnipodDriverState.Initalized_PodInitializing); } else { omnipodUtil.setDriverState(OmnipodDriverState.Initalized_PodAttached); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/pages/PodInfoFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/pages/PodInfoFragment.java index 65d032739d..9f8df4a783 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/pages/PodInfoFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/pages/PodInfoFragment.java @@ -19,7 +19,7 @@ import javax.inject.Inject; import dagger.android.support.DaggerFragment; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil; @@ -85,27 +85,26 @@ public class PodInfoFragment extends DaggerFragment { private boolean createDataOfPod() { - PodSessionState podSessionState = omnipodUtil.getPodSessionState(); + PodStateManager podStateManager = omnipodUtil.getPodStateManager(); -// PodSessionState podSessionState = new PodSessionState(DateTimeZone.UTC, -// 483748738, -// new DateTime(), -// new FirmwareVersion(1,0,0), -// new FirmwareVersion(1,0,0), -// 574875, -// 5487584, -// 1, -// 1 -// ); - - if (podSessionState == null) + if (podStateManager == null) return false; mCurrentReviewItems = new ArrayList<>(); - mCurrentReviewItems.add(new ReviewItem("Pod Address", "" + podSessionState.getAddress(), "33")); - mCurrentReviewItems.add(new ReviewItem("Activated At", podSessionState.getActivatedAt().toString("dd.MM.yyyy HH:mm:ss"), "34")); - mCurrentReviewItems.add(new ReviewItem("Firmware Version", podSessionState.getPiVersion().toString(), "35")); - mCurrentReviewItems.add(new ReviewItem("LOT", "" + podSessionState.getLot(), "36")); + mCurrentReviewItems.add(new ReviewItem("Pod Address", "" + podStateManager.getAddress(), "33")); + mCurrentReviewItems.add(new ReviewItem("Activated At", podStateManager.getActivatedAt() == null ? "Not activated yet" : podStateManager.getActivatedAt().toString("dd.MM.yyyy HH:mm:ss"), "34")); + if (podStateManager.getLot() != null) { + mCurrentReviewItems.add(new ReviewItem("LOT", "" + podStateManager.getLot(), "35")); + } + if(podStateManager.getTid() != null) { + mCurrentReviewItems.add(new ReviewItem("TID", "" + podStateManager.getLot(), "36")); + } + if (podStateManager.getPiVersion() != null) { + mCurrentReviewItems.add(new ReviewItem("Pi Version", podStateManager.getPiVersion().toString(), "37")); + } + if (podStateManager.getPmVersion() != null) { + mCurrentReviewItems.add(new ReviewItem("Pm Version", podStateManager.getPmVersion().toString(), "38")); + } return true; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/OmnipodPumpStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/OmnipodPumpStatus.java index 05ca9d6ad5..e01acd7d9c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/OmnipodPumpStatus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/OmnipodPumpStatus.java @@ -15,9 +15,8 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLin 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.medtronic.defs.PumpDeviceState; -import info.nightscout.androidaps.plugins.pump.medtronic.events.EventMedtronicDeviceStatusChange; import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodDeviceState; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodDeviceStatusChange; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; import info.nightscout.androidaps.utils.resources.ResourceHelper; @@ -47,7 +46,7 @@ public class OmnipodPumpStatus extends PumpStatus { public Double tempBasalAmount = 0.0d; public Integer tempBasalLength; public long tempBasalPumpId; - public PodSessionState podSessionState; + public PodStateManager podStateManager; public PumpType pumpType; public String regexMac = "([\\da-fA-F]{1,2}(?:\\:|$)){6}"; @@ -142,7 +141,7 @@ public class OmnipodPumpStatus extends PumpStatus { ", tempBasalEnd=" + tempBasalEnd + ", tempBasalAmount=" + tempBasalAmount + ", tempBasalLength=" + tempBasalLength + - ", podSessionState=" + podSessionState + + ", podStateManager=" + podStateManager + ", regexMac='" + regexMac + '\'' + ", podNumber='" + podNumber + '\'' + ", podDeviceState=" + podDeviceState + diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java index f8c67f5471..fe232cf912 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java @@ -60,6 +60,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.PodReturne import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoRecentPulseLog; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSet; import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSlot; import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertType; import info.nightscout.androidaps.plugins.pump.omnipod.defs.FaultEventCode; @@ -69,7 +70,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInitActionType; import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInitReceiver; import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BasalSchedule; import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BasalScheduleEntry; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus; import info.nightscout.androidaps.plugins.pump.omnipod.driver.db.PodHistory; import info.nightscout.androidaps.plugins.pump.omnipod.driver.db.PodHistoryEntryType; @@ -103,7 +104,7 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface } public AapsOmnipodManager(OmnipodCommunicationManager communicationService, - PodSessionState podState, + PodStateManager podStateManager, OmnipodPumpStatus _pumpStatus, OmnipodUtil omnipodUtil, AAPSLogger aapsLogger, @@ -120,17 +121,26 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface this.activePlugin = activePlugin; this.pumpStatus = _pumpStatus; - delegate = new OmnipodManager(aapsLogger, sp, communicationService, podState, podSessionState -> { + podStateManager.setStateChangedHandler(manager -> { // Handle pod state changes - omnipodUtil.setPodSessionState(podSessionState); - updatePumpStatus(podSessionState); + // FIXME only set once (?) (before instantiating AapsOmnipodManager) + // Maybe not, it seems to not only set something, but also fire an event + omnipodUtil.setPodStateManager(manager); + + updatePumpStatus(manager); }); + + delegate = new OmnipodManager(aapsLogger, sp, communicationService, podStateManager); instance = this; } - private void updatePumpStatus(PodSessionState podSessionState) { + public PodStateManager getPodStateManager() { + return delegate.getPodStateManager(); + } + + private void updatePumpStatus(PodStateManager podStateManager) { if (pumpStatus != null) { - if (podSessionState == null) { + if (!podStateManager.hasState()) { pumpStatus.ackAlertsText = null; pumpStatus.ackAlertsAvailable = false; pumpStatus.lastBolusTime = null; @@ -142,8 +152,8 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface sendEvent(new EventRefreshOverview("Omnipod Pump", false)); } else { // Update active alerts - if (podSessionState.hasActiveAlerts()) { - List alerts = translateActiveAlerts(podSessionState); + if (podStateManager.hasActiveAlerts()) { + List alerts = translateActiveAlerts(podStateManager); String alertsText = TextUtils.join("\n", alerts); if (!pumpStatus.ackAlertsAvailable || !alertsText.equals(pumpStatus.ackAlertsText)) { @@ -163,15 +173,15 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface // Update other info: last bolus, units remaining, suspended if (!Objects.equals(lastBolusTime, pumpStatus.lastBolusTime) // || !Objects.equals(lastBolusUnits, pumpStatus.lastBolusAmount) // - || !isReservoirStatusUpToDate(pumpStatus, podSessionState.getReservoirLevel()) - || podSessionState.isSuspended() != PumpStatusType.Suspended.equals(pumpStatus.pumpStatusType)) { + || !isReservoirStatusUpToDate(pumpStatus, podStateManager.getReservoirLevel()) + || podStateManager.isSuspended() != PumpStatusType.Suspended.equals(pumpStatus.pumpStatusType)) { pumpStatus.lastBolusTime = lastBolusTime; pumpStatus.lastBolusAmount = lastBolusUnits; - pumpStatus.reservoirRemainingUnits = podSessionState.getReservoirLevel() == null ? 75.0 : podSessionState.getReservoirLevel(); - pumpStatus.pumpStatusType = podSessionState.isSuspended() ? PumpStatusType.Suspended : PumpStatusType.Running; + pumpStatus.reservoirRemainingUnits = podStateManager.getReservoirLevel() == null ? 75.0 : podStateManager.getReservoirLevel(); + pumpStatus.pumpStatusType = podStateManager.isSuspended() ? PumpStatusType.Suspended : PumpStatusType.Running; sendEvent(new EventOmnipodPumpValuesChanged()); - if (podSessionState.isSuspended() != PumpStatusType.Suspended.equals(pumpStatus.pumpStatusType)) { + if (podStateManager.isSuspended() != PumpStatusType.Suspended.equals(pumpStatus.pumpStatusType)) { sendEvent(new EventRefreshOverview("Omnipod Pump", false)); } } @@ -179,31 +189,31 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface } } + private List translateActiveAlerts(PodStateManager podStateManager) { + List translatedAlerts = new ArrayList<>(); + AlertSet activeAlerts = podStateManager.getActiveAlerts(); + if (activeAlerts == null) { + return translatedAlerts; + } + for (AlertSlot alertSlot : activeAlerts.getAlertSlots()) { + translatedAlerts.add(translateAlertType(podStateManager.getConfiguredAlertType(alertSlot))); + } + return translatedAlerts; + } + private static boolean isReservoirStatusUpToDate(OmnipodPumpStatus pumpStatus, Double unitsRemaining) { double expectedUnitsRemaining = unitsRemaining == null ? 75.0 : unitsRemaining; return Math.abs(expectedUnitsRemaining - pumpStatus.reservoirRemainingUnits) < 0.000001; } - private List translateActiveAlerts(PodSessionState podSessionState) { - List alerts = new ArrayList<>(); - for (AlertSlot alertSlot : podSessionState.getActiveAlerts().getAlertSlots()) { - alerts.add(translateAlertType(podSessionState.getConfiguredAlertType(alertSlot))); - } - return alerts; - } - @Override public PumpEnactResult initPod(PodInitActionType podInitActionType, PodInitReceiver podInitReceiver, Profile profile) { long time = System.currentTimeMillis(); if (PodInitActionType.PairAndPrimeWizardStep.equals(podInitActionType)) { try { - int address = obtainNextPodAddress(); - - Disposable disposable = delegate.pairAndPrime(address).subscribe(res -> // + Disposable disposable = delegate.pairAndPrime().subscribe(res -> // handleSetupActionResult(podInitActionType, podInitReceiver, res, time, null)); - removeNextPodAddress(); - return new PumpEnactResult(injector).success(true).enacted(true); } catch (Exception ex) { String comment = handleAndTranslateException(ex); @@ -265,8 +275,6 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface podInitReceiver.returnInitTaskStatus(PodInitActionType.DeactivatePodWizardStep, true, null); - this.omnipodUtil.setPodSessionState(null); - return new PumpEnactResult(injector).success(true).enacted(true); } @@ -302,13 +310,10 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface @Override public PumpEnactResult resetPodStatus() { - delegate.resetPodState(true); + getPodStateManager().removeState(); reportImplicitlyCanceledTbr(); - this.omnipodUtil.setPodSessionState(null); - this.omnipodUtil.removeNextPodAddress(); - addSuccessToHistory(System.currentTimeMillis(), PodHistoryEntryType.ResetPodState, null); return new PumpEnactResult(injector).success(true).enacted(true); @@ -363,8 +368,8 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface activePlugin.getActiveTreatments().addToHistoryTreatment(detailedBolusInfo, false); - if (delegate.getPodState().hasFaultEvent()) { - showPodFaultErrorDialog(delegate.getPodState().getFaultEvent().getFaultEventCode(), R.raw.urgentalarm); + if (delegate.getPodStateManager().hasFaultEvent()) { + showPodFaultErrorDialog(delegate.getPodStateManager().getFaultEvent().getFaultEventCode(), R.raw.urgentalarm); } return new PumpEnactResult(injector).success(true).enacted(true).bolusDelivered(unitsDelivered); @@ -463,7 +468,7 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface @Override public void setPumpStatus(OmnipodPumpStatus pumpStatus) { this.pumpStatus = pumpStatus; - updatePumpStatus(delegate.getPodState()); + updatePumpStatus(delegate.getPodStateManager()); } // TODO should we add this to the OmnipodCommunicationManager interface? @@ -598,20 +603,6 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface return podHistory.getPumpId(); } - private int obtainNextPodAddress() { - Integer nextPodAddress = this.omnipodUtil.getNextPodAddress(); - if (nextPodAddress == null) { - nextPodAddress = OmnipodManager.generateRandomAddress(); - this.omnipodUtil.setNextPodAddress(nextPodAddress); - } - - return nextPodAddress; - } - - private void removeNextPodAddress() { - this.omnipodUtil.removeNextPodAddress(); - } - private void handleSetupActionResult(PodInitActionType podInitActionType, PodInitReceiver podInitReceiver, SetupActionResult res, long time, Profile profile) { String comment = null; switch (res.getResultType()) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java index 75479709e2..3e278f03a8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java @@ -25,6 +25,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.defs.DeliveryStatus; import info.nightscout.androidaps.plugins.pump.omnipod.defs.FirmwareVersion; import info.nightscout.androidaps.plugins.pump.omnipod.defs.SetupProgress; import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BasalSchedule; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateChangedHandler; import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmniCRC; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; @@ -34,11 +35,12 @@ import info.nightscout.androidaps.utils.sharedPreferences.SP; public class AapsPodStateManager implements PodStateManager { - @Inject private AAPSLogger aapsLogger; - @Inject private SP sp; - @Inject private OmnipodUtil omnipodUtil; + @Inject protected AAPSLogger aapsLogger; + @Inject protected SP sp; + @Inject protected OmnipodUtil omnipodUtil; private PodState podState; + private PodStateChangedHandler stateChangedHandler; public AapsPodStateManager(HasAndroidInjector injector) { injector.androidInjector().inject(this); @@ -56,6 +58,15 @@ public class AapsPodStateManager implements PodStateManager { persistPodState(); } + @Override + public void initState(int address) { + if (hasState()) { + throw new IllegalStateException("Can not init a new pod state: podState <> null"); + } + podState = new PodState(address); + persistPodState(); + } + @Override public boolean isPaired() { return hasState() // && podState.getLot() != null && podState.getTid() != null // @@ -64,6 +75,7 @@ public class AapsPodStateManager implements PodStateManager { && podState.getSetupProgress() != null; } + @Override public void setPairingParameters(int lot, int tid, FirmwareVersion piVersion, FirmwareVersion pmVersion, DateTimeZone timeZone) { if (!hasState()) { throw new IllegalStateException("Cannot set pairing parameters: podState is null"); @@ -81,13 +93,16 @@ public class AapsPodStateManager implements PodStateManager { throw new IllegalArgumentException("Cannot set pairing parameters: timeZone can not be null"); } - podState.setLot(lot); - podState.setTid(tid); - podState.setPiVersion(piVersion); - podState.setPmVersion(pmVersion); - podState.setTimeZone(timeZone); - podState.setNonceState(new NonceState(lot, tid)); - podState.setSetupProgress(SetupProgress.ADDRESS_ASSIGNED); + setAndStore(() -> { + podState.setLot(lot); + podState.setTid(tid); + podState.setPiVersion(piVersion); + podState.setPmVersion(pmVersion); + podState.setTimeZone(timeZone); + podState.setNonceState(new NonceState(lot, tid)); + podState.setSetupProgress(SetupProgress.ADDRESS_ASSIGNED); + podState.getConfiguredAlerts().put(AlertSlot.SLOT7, AlertType.FINISH_SETUP_REMINDER); + }); } @Override public int getAddress() { @@ -118,7 +133,7 @@ public class AapsPodStateManager implements PodStateManager { setAndStore(() -> podState.setPacketNumber(podState.getPacketNumber() + 1)); } - @Override public void resyncNonce(int syncWord, int sentNonce, int sequenceNumber) { + @Override public synchronized void resyncNonce(int syncWord, int sentNonce, int sequenceNumber) { if (!isPaired()) { throw new IllegalStateException("Cannot resync nonce: Pod is not paired yet"); } @@ -133,14 +148,14 @@ public class AapsPodStateManager implements PodStateManager { setAndStore(() -> podState.setNonceState(nonceState)); } - @Override public int getCurrentNonce() { + @Override public synchronized int getCurrentNonce() { if (!isPaired()) { throw new IllegalStateException("Cannot get current nonce: Pod is not paired yet"); } return podState.getNonceState().getCurrentNonce(); } - @Override public void advanceToNextNonce() { + @Override public synchronized void advanceToNextNonce() { if (!isPaired()) { throw new IllegalStateException("Cannot advance to next nonce: Pod is not paired yet"); } @@ -292,12 +307,35 @@ public class AapsPodStateManager implements PodStateManager { }); } + @Override + public void setStateChangedHandler(PodStateChangedHandler handler) { + // FIXME this is an ugly workaround for not being able to serialize the PodStateChangedHandler + if (stateChangedHandler != null) { + throw new IllegalStateException("A PodStateChangedHandler has already been already registered"); + } + stateChangedHandler = handler; + } + private void setAndStore(Runnable runnable) { if (!hasState()) { throw new IllegalStateException("Cannot mutate PodState: podState is null"); } runnable.run(); persistPodState(); + notifyPodStateChanged(); + } + + private void persistPodState() { + Gson gson = omnipodUtil.getGsonInstance(); + String gsonValue = gson.toJson(podState); + aapsLogger.info(LTag.PUMPCOMM, "PodState-SP: Saved PodState to SharedPreferences: " + gsonValue); + sp.putString(OmnipodConst.Prefs.PodState, gsonValue); + } + + private void notifyPodStateChanged() { + if (stateChangedHandler != null) { + stateChangedHandler.handle(this); + } } // Not actually "safe" as it throws an Exception, but it prevents NPEs @@ -308,13 +346,6 @@ public class AapsPodStateManager implements PodStateManager { return supplier.get(); } - private void persistPodState() { - Gson gson = omnipodUtil.getGsonInstance(); - String gsonValue = gson.toJson(podState); - aapsLogger.info(LTag.PUMPCOMM, "PodState-SP: Saved PodState to SharedPreferences: " + gsonValue); - sp.putString(OmnipodConst.Prefs.PodState, gsonValue); - } - private void loadPodState() { podState = null; @@ -330,6 +361,14 @@ public class AapsPodStateManager implements PodStateManager { aapsLogger.error(LTag.PUMPCOMM, "PodState-SP: could not deserialize PodState", ex); } } + + notifyPodStateChanged(); + } + + @Override public String toString() { + return "AapsPodStateManager{" + + "podState=" + podState + + '}'; } private static class PodState { @@ -506,6 +545,30 @@ public class AapsPodStateManager implements PodStateManager { public Map getConfiguredAlerts() { return configuredAlerts; } + + @Override public String toString() { + return "PodState{" + + "address=" + address + + ", lot=" + lot + + ", tid=" + tid + + ", piVersion=" + piVersion + + ", pmVersion=" + pmVersion + + ", packetNumber=" + packetNumber + + ", messageNumber=" + messageNumber + + ", timeZone=" + timeZone + + ", activatedAt=" + activatedAt + + ", expiresAt=" + expiresAt + + ", faultEvent=" + faultEvent + + ", reservoirLevel=" + reservoirLevel + + ", suspended=" + suspended + + ", nonceState=" + nonceState + + ", setupProgress=" + setupProgress + + ", lastDeliveryStatus=" + lastDeliveryStatus + + ", activeAlerts=" + activeAlerts + + ", basalSchedule=" + basalSchedule + + ", configuredAlerts=" + configuredAlerts + + '}'; + } } private static class NonceState { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/events/EventOmnipodDeviceStatusChange.kt b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/events/EventOmnipodDeviceStatusChange.kt index 7e7cc87279..41f4cfca9b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/events/EventOmnipodDeviceStatusChange.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/events/EventOmnipodDeviceStatusChange.kt @@ -6,7 +6,7 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLin import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpDeviceState import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodCommandType import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodDeviceState -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager /** * Created by andy on 4.8.2019 @@ -15,7 +15,7 @@ class EventOmnipodDeviceStatusChange : Event { var rileyLinkServiceState: RileyLinkServiceState? = null var rileyLinkError: RileyLinkError? = null - var podSessionState: PodSessionState? = null + var podStateManager: PodStateManager? = null var errorDescription: String? = null var podDeviceState: PodDeviceState? = null var pumpDeviceState: PumpDeviceState? = null @@ -32,8 +32,8 @@ class EventOmnipodDeviceStatusChange : Event { } - constructor(podSessionState: PodSessionState?) { - this.podSessionState = podSessionState + constructor(podStateManager: PodStateManager?) { + this.podStateManager = podStateManager } constructor(errorDescription: String?) { @@ -58,7 +58,7 @@ class EventOmnipodDeviceStatusChange : Event { return ("EventOmnipodDeviceStatusChange [" // + "rileyLinkServiceState=" + rileyLinkServiceState + ", rileyLinkError=" + rileyLinkError // - + ", podSessionState=" + podSessionState // + + ", podStateManager=" + podStateManager // + ", podDeviceState=" + podDeviceState + "]") } } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java index f401e4ddd1..a84996dc53 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java @@ -23,9 +23,10 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.Riley import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpDeviceState; import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodPumpPlugin; import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus; import info.nightscout.androidaps.plugins.pump.omnipod.driver.comm.AapsOmnipodManager; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.comm.AapsPodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.driver.ui.OmnipodUIComm; import info.nightscout.androidaps.plugins.pump.omnipod.driver.ui.OmnipodUIPostprocessor; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; @@ -106,19 +107,23 @@ public class RileyLinkOmnipodService extends RileyLinkService { } private void initializeErosOmnipodManager() { - if (AapsOmnipodManager.getInstance() == null) { - PodSessionState podState = omnipodUtil.loadSessionState(); + AapsOmnipodManager instance = AapsOmnipodManager.getInstance(); + if (instance == null) { + PodStateManager podStateManager = new AapsPodStateManager(injector); + omnipodUtil.setPodStateManager(podStateManager); + OmnipodCommunicationManager omnipodCommunicationService = new OmnipodCommunicationManager(injector, rfspy); //omnipodCommunicationService.setPumpStatus(omnipodPumpStatus); this.omnipodCommunicationManager = omnipodCommunicationService; - this.aapsOmnipodManager = new AapsOmnipodManager(omnipodCommunicationService, podState, omnipodPumpStatus, + aapsOmnipodManager = new AapsOmnipodManager(omnipodCommunicationService, podStateManager, omnipodPumpStatus, omnipodUtil, aapsLogger, rxBus, sp, resourceHelper, injector, activePlugin); omnipodUIComm = new OmnipodUIComm(injector, aapsLogger, omnipodUtil, omnipodUIPostprocessor, aapsOmnipodManager); } else { - aapsOmnipodManager = AapsOmnipodManager.getInstance(); + aapsOmnipodManager = instance; + omnipodUtil.setPodStateManager(instance.getPodStateManager()); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodUtil.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodUtil.java index 9c4f6cabe5..c008cee6e9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodUtil.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodUtil.java @@ -8,7 +8,6 @@ import com.google.gson.JsonDeserializer; import com.google.gson.JsonPrimitive; import com.google.gson.JsonSerializer; -import org.apache.commons.lang3.StringUtils; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.joda.time.format.ISODateTimeFormat; @@ -16,21 +15,18 @@ import org.joda.time.format.ISODateTimeFormat; import javax.inject.Inject; import javax.inject.Singleton; -import dagger.android.HasAndroidInjector; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.interfaces.ActivePluginProvider; import info.nightscout.androidaps.logging.AAPSLogger; -import info.nightscout.androidaps.logging.LTag; import info.nightscout.androidaps.plugins.bus.RxBusWrapper; import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.data.RLHistoryItem; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodManager; import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodCommandType; import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodPodType; import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodDeviceState; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodDriverState; import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus; import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodDeviceStatusChange; @@ -49,13 +45,10 @@ public class OmnipodUtil { private final OmnipodPumpStatus omnipodPumpStatus; private final ActivePluginProvider activePlugins; private final SP sp; - private final HasAndroidInjector injector; private boolean lowLevelDebug = true; private OmnipodCommandType currentCommand; private Gson gsonInstance = createGson(); - //private static PodSessionState podSessionState; - //private static PodDeviceState podDeviceState; private OmnipodPodType omnipodPodType; private OmnipodDriverState driverState = OmnipodDriverState.NotInitalized; @@ -67,8 +60,7 @@ public class OmnipodUtil { RileyLinkUtil rileyLinkUtil, OmnipodPumpStatus omnipodPumpStatus, SP sp, - ActivePluginProvider activePlugins, - HasAndroidInjector injector + ActivePluginProvider activePlugins ) { this.aapsLogger = aapsLogger; this.rxBus = rxBus; @@ -76,7 +68,6 @@ public class OmnipodUtil { this.omnipodPumpStatus = omnipodPumpStatus; this.sp = sp; this.activePlugins = activePlugins; - this.injector = injector; } @@ -148,9 +139,9 @@ public class OmnipodUtil { } - public void setPodSessionState(PodSessionState podSessionState) { - omnipodPumpStatus.podSessionState = podSessionState; - rxBus.send(new EventOmnipodDeviceStatusChange(podSessionState)); + public void setPodStateManager(PodStateManager podStateManager) { + omnipodPumpStatus.podStateManager = podStateManager; + rxBus.send(new EventOmnipodDeviceStatusChange(podStateManager)); } @@ -174,8 +165,8 @@ public class OmnipodUtil { } - public PodSessionState getPodSessionState() { - return omnipodPumpStatus.podSessionState; + public PodStateManager getPodStateManager() { + return omnipodPumpStatus.podStateManager; } @@ -202,28 +193,6 @@ public class OmnipodUtil { return this.gsonInstance; } - public Integer getNextPodAddress() { - if (sp.contains(OmnipodConst.Prefs.NextPodAddress)) { - int nextPodAddress = sp.getInt(OmnipodConst.Prefs.NextPodAddress, 0); - if (OmnipodManager.isValidAddress(nextPodAddress)) { - return nextPodAddress; - } - } - return null; - } - - public boolean hasNextPodAddress() { - return getNextPodAddress() != null; - } - - public void setNextPodAddress(int address) { - sp.putInt(OmnipodConst.Prefs.NextPodAddress, address); - } - - public void removeNextPodAddress() { - sp.remove(OmnipodConst.Prefs.NextPodAddress); - } - public AAPSLogger getAapsLogger() { return this.aapsLogger; } @@ -231,25 +200,4 @@ public class OmnipodUtil { public SP getSp() { return this.sp; } - - public PodSessionState loadSessionState() { - PodSessionState podSessionState = null; - - String storedPodState = sp.getString(OmnipodConst.Prefs.PodState, ""); - if (StringUtils.isEmpty(storedPodState)) { - aapsLogger.info(LTag.PUMP, "PodSessionState-SP: no PodSessionState present in SharedPreferences"); - } else { - aapsLogger.info(LTag.PUMP, "PodSessionState-SP: loaded from SharedPreferences: " + storedPodState); - try { - podSessionState = gsonInstance.fromJson(storedPodState, PodSessionState.class); - podSessionState.injectDaggerClass(injector); - } catch (Exception ex) { - aapsLogger.error(LTag.PUMPCOMM, "Could not deserialize Pod state", ex); - } - } - - setPodSessionState(podSessionState); - - return podSessionState; - } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod_dash/comm/OmnipodDashCommunicationManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod_dash/comm/OmnipodDashCommunicationManager.java index 4f869bd286..992a248994 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod_dash/comm/OmnipodDashCommunicationManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod_dash/comm/OmnipodDashCommunicationManager.java @@ -11,7 +11,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.pod import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodCommunicationManagerInterface; import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInitActionType; import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInitReceiver; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus; /** @@ -34,7 +34,7 @@ public class OmnipodDashCommunicationManager implements OmnipodCommunicationMana // RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L); } - private PodSessionState getPodSessionState() { + private PodStateManager getPodStateManager() { return null; } diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodSessionStateTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/AapsPodStateManagerTest.java similarity index 62% rename from app/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodSessionStateTest.java rename to app/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/AapsPodStateManagerTest.java index a7ba9cb861..85d8dd897e 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodSessionStateTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/AapsPodStateManagerTest.java @@ -11,10 +11,11 @@ import org.mockito.Mock; import dagger.android.HasAndroidInjector; import info.nightscout.androidaps.plugins.pump.omnipod.defs.FirmwareVersion; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.comm.AapsPodStateManager; import static org.junit.Assert.assertEquals; -public class PodSessionStateTest { +public class AapsPodStateManagerTest { @Mock HasAndroidInjector hasAndroidInjector; @Test @@ -24,17 +25,16 @@ public class PodSessionStateTest { DateTimeZone.setDefault(timeZone); DateTime now = new DateTime(2020, 1, 1, 1, 2, 3, timeZone); - DateTime initialized = now.minus(Duration.standardDays(1)); DateTimeUtils.setCurrentMillisFixed(now.getMillis()); - PodSessionState podSessionState = new PodSessionState(timeZone, 0x0, - new FirmwareVersion(1, 1, 1), - new FirmwareVersion(2, 2, 2), - 0, 0, 0, 0, hasAndroidInjector); + AapsPodStateManager podStateManager = new AapsPodStateManager(hasAndroidInjector); + podStateManager.initState(0x0); + podStateManager.setPairingParameters(0, 0, new FirmwareVersion(1, 1, 1), + new FirmwareVersion(2, 2, 2), timeZone); - assertEquals(now, podSessionState.getTime()); - assertEquals(Duration.standardHours(1).plus(Duration.standardMinutes(2).plus(Duration.standardSeconds(3))), podSessionState.getScheduleOffset()); + assertEquals(now, podStateManager.getTime()); + assertEquals(Duration.standardHours(1).plus(Duration.standardMinutes(2).plus(Duration.standardSeconds(3))), podStateManager.getScheduleOffset()); } @Test @@ -44,22 +44,21 @@ public class PodSessionStateTest { DateTimeZone.setDefault(timeZone); DateTime now = new DateTime(2020, 1, 1, 1, 2, 3, timeZone); - DateTime initialized = now.minus(Duration.standardDays(1)); DateTimeUtils.setCurrentMillisFixed(now.getMillis()); - PodSessionState podSessionState = new PodSessionState(timeZone, 0x0, - new FirmwareVersion(1, 1, 1), - new FirmwareVersion(2, 2, 2), - 0, 0, 0, 0, hasAndroidInjector); + AapsPodStateManager podStateManager = new AapsPodStateManager(hasAndroidInjector); + podStateManager.initState(0x0); + podStateManager.setPairingParameters(0, 0, new FirmwareVersion(1, 1, 1), + new FirmwareVersion(2, 2, 2), timeZone); DateTimeZone newTimeZone = DateTimeZone.forOffsetHours(2); DateTimeZone.setDefault(newTimeZone); // The system time zone has been updated, but the pod session state's time zone hasn't // So the pods time should not have been changed - assertEquals(now, podSessionState.getTime()); - assertEquals(Duration.standardHours(1).plus(Duration.standardMinutes(2).plus(Duration.standardSeconds(3))), podSessionState.getScheduleOffset()); + assertEquals(now, podStateManager.getTime()); + assertEquals(Duration.standardHours(1).plus(Duration.standardMinutes(2).plus(Duration.standardSeconds(3))), podStateManager.getScheduleOffset()); } @Test @@ -69,23 +68,22 @@ public class PodSessionStateTest { DateTimeZone.setDefault(timeZone); DateTime now = new DateTime(2020, 1, 1, 1, 2, 3, timeZone); - DateTime initialized = now.minus(Duration.standardDays(1)); DateTimeUtils.setCurrentMillisFixed(now.getMillis()); - PodSessionState podSessionState = new PodSessionState(timeZone, 0x0, - new FirmwareVersion(1, 1, 1), - new FirmwareVersion(2, 2, 2), - 0, 0, 0, 0, hasAndroidInjector); + AapsPodStateManager podStateManager = new AapsPodStateManager(hasAndroidInjector); + podStateManager.initState(0x0); + podStateManager.setPairingParameters(0, 0, new FirmwareVersion(1, 1, 1), + new FirmwareVersion(2, 2, 2), timeZone); DateTimeZone newTimeZone = DateTimeZone.forOffsetHours(2); DateTimeZone.setDefault(newTimeZone); - podSessionState.setTimeZone(newTimeZone); + podStateManager.setTimeZone(newTimeZone); // Both the system time zone have been updated // So the pods time should have been changed (to +2 hours) - assertEquals(now.withZone(newTimeZone), podSessionState.getTime()); - assertEquals(Duration.standardHours(3).plus(Duration.standardMinutes(2).plus(Duration.standardSeconds(3))), podSessionState.getScheduleOffset()); + assertEquals(now.withZone(newTimeZone), podStateManager.getTime()); + assertEquals(Duration.standardHours(3).plus(Duration.standardMinutes(2).plus(Duration.standardSeconds(3))), podStateManager.getScheduleOffset()); } @After From 3bc53544a2b97b83c4152892dd9170b146bd550d Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Sat, 8 Aug 2020 18:37:10 +0200 Subject: [PATCH 05/17] Bug fixes and improvements in PodStateManager stuff --- .../plugins/pump/omnipod/OmnipodPumpPlugin.java | 8 ++++---- .../plugins/pump/omnipod/comm/OmnipodManager.java | 12 ++---------- .../pump/omnipod/dialogs/PodManagementActivity.kt | 2 +- .../omnipod/driver/comm/AapsOmnipodManager.java | 15 ++++++++++----- 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java index a7a0eba086..46040c78ab 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java @@ -487,17 +487,17 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump public boolean isSuspended() { return (omnipodUtil.getDriverState() == OmnipodDriverState.Initalized_NoPod) || - (omnipodUtil.getPodStateManager() != null && omnipodUtil.getPodStateManager().isSuspended()); + (omnipodUtil.getPodStateManager() != null && omnipodUtil.getPodStateManager().hasState() && omnipodUtil.getPodStateManager().isSuspended()); // return (pumpStatusLocal != null && !pumpStatusLocal.podAvailable) || -// (OmnipodUtil.getPodStateManager() != null && OmnipodUtil.getPodStateManager().isSuspended()); +// (OmnipodUtil.getPodStateManager() != null && omnipodUtil.getPodStateManager().hasState() && OmnipodUtil.getPodStateManager().isSuspended()); // // TODO ddd // return (OmnipodUtil.getDriverState() == OmnipodDriverState.Initalized_NoPod) || -// (OmnipodUtil.getPodStateManager() != null && OmnipodUtil.getPodStateManager().isSuspended()); +// (OmnipodUtil.getPodStateManager() != null && omnipodUtil.getPodStateManager().hasState() && OmnipodUtil.getPodStateManager().isSuspended()); // // return (pumpStatusLocal != null && !pumpStatusLocal.podAvailable) || -// (OmnipodUtil.getPodStateManager() != null && OmnipodUtil.getPodStateManager().isSuspended()); +// (OmnipodUtil.getPodStateManager() != null && omnipodUtil.getPodStateManager().hasState() && OmnipodUtil.getPodStateManager().isSuspended()); } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodManager.java index 6c12b27ab2..3f3974bb21 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodManager.java @@ -81,7 +81,7 @@ public class OmnipodManager { logStartingCommandExecution("pairAndPrime"); try { - if (!podStateManager.hasState() || !podStateManager.getSetupProgress().isBefore(SetupProgress.POD_CONFIGURED)) { + if (!podStateManager.hasState() || !podStateManager.isPaired() || podStateManager.getSetupProgress().isBefore(SetupProgress.POD_CONFIGURED)) { // Always send both 0x07 and 0x03 on retries communicationService.executeAction( new AssignAddressAction(podStateManager)); @@ -105,7 +105,7 @@ public class OmnipodManager { } public synchronized Single insertCannula(BasalSchedule basalSchedule) { - if (!podStateManager.hasState() || podStateManager.getSetupProgress().isBefore(SetupProgress.PRIMING_FINISHED)) { + if (!podStateManager.hasState() || !podStateManager.isPaired() || podStateManager.getSetupProgress().isBefore(SetupProgress.PRIMING_FINISHED)) { throw new IllegalSetupProgressException(SetupProgress.PRIMING_FINISHED, !podStateManager.hasState() ? null : podStateManager.getSetupProgress()); } else if (podStateManager.getSetupProgress().isAfter(SetupProgress.CANNULA_INSERTING)) { throw new IllegalSetupProgressException(SetupProgress.CANNULA_INSERTING, podStateManager.getSetupProgress()); @@ -455,14 +455,6 @@ public class OmnipodManager { } } - public PodStateManager getPodStateManager() { - return this.podStateManager; - } - - public String getPodStateAsString() { - return podStateManager.hasState() ? podStateManager.toString() : "null"; - } - // Only works for commands with nonce resyncable message blocks // FIXME method is too big, needs refactoring private StatusResponse executeAndVerify(VerifiableAction runnable) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/PodManagementActivity.kt b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/PodManagementActivity.kt index c37a2af49f..012e7c6386 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/PodManagementActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/PodManagementActivity.kt @@ -99,7 +99,7 @@ class PodManagementActivity : NoSplashAppCompatActivity() { wizardPagerContext.clearContext() wizardPagerContext.pagerSettings = pagerSettings val podStateManager = omnipodUtil.getPodStateManager() - val isFullInit = podStateManager == null || podStateManager.setupProgress.isBefore(SetupProgress.PRIMING_FINISHED) + val isFullInit = podStateManager == null || !podStateManager.isPaired || podStateManager.setupProgress.isBefore(SetupProgress.PRIMING_FINISHED) if (isFullInit) { wizardPagerContext.wizardModel = FullInitPodWizardModel(applicationContext) } else { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java index fe232cf912..928157f06b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java @@ -84,6 +84,7 @@ import io.reactivex.disposables.Disposable; public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface { + private final PodStateManager podStateManager; private OmnipodUtil omnipodUtil; private AAPSLogger aapsLogger; private RxBusWrapper rxBus; @@ -113,6 +114,10 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface ResourceHelper resourceHelper, HasAndroidInjector injector, ActivePluginProvider activePlugin) { + if (podStateManager == null) { + throw new IllegalArgumentException("Pod state manager can not be null"); + } + this.podStateManager = podStateManager; this.omnipodUtil = omnipodUtil; this.aapsLogger = aapsLogger; this.rxBus = rxBus; @@ -135,7 +140,7 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface } public PodStateManager getPodStateManager() { - return delegate.getPodStateManager(); + return podStateManager; } private void updatePumpStatus(PodStateManager podStateManager) { @@ -368,8 +373,8 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface activePlugin.getActiveTreatments().addToHistoryTreatment(detailedBolusInfo, false); - if (delegate.getPodStateManager().hasFaultEvent()) { - showPodFaultErrorDialog(delegate.getPodStateManager().getFaultEvent().getFaultEventCode(), R.raw.urgentalarm); + if (podStateManager.hasFaultEvent()) { + showPodFaultErrorDialog(podStateManager.getFaultEvent().getFaultEventCode(), R.raw.urgentalarm); } return new PumpEnactResult(injector).success(true).enacted(true).bolusDelivered(unitsDelivered); @@ -468,7 +473,7 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface @Override public void setPumpStatus(OmnipodPumpStatus pumpStatus) { this.pumpStatus = pumpStatus; - updatePumpStatus(delegate.getPodStateManager()); + updatePumpStatus(podStateManager); } // TODO should we add this to the OmnipodCommunicationManager interface? @@ -553,7 +558,7 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface } public String getPodStateAsString() { - return delegate.getPodStateAsString(); + return podStateManager.toString(); } private void reportImplicitlyCanceledTbr() { From 76d267dce4af9143f4d2a53bd09d8fb193fb283e Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Sat, 8 Aug 2020 18:44:33 +0200 Subject: [PATCH 06/17] Prevent NPE --- .../plugins/pump/omnipod/comm/action/InsertCannulaAction.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/InsertCannulaAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/InsertCannulaAction.java index 559b41e109..c8da669fb8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/InsertCannulaAction.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/InsertCannulaAction.java @@ -42,7 +42,7 @@ public class InsertCannulaAction implements OmnipodAction { @Override public StatusResponse execute(OmnipodCommunicationManager communicationService) { - if (podStateManager.getSetupProgress().isBefore(SetupProgress.PRIMING_FINISHED)) { + if (!podStateManager.isPaired() || podStateManager.getSetupProgress().isBefore(SetupProgress.PRIMING_FINISHED)) { throw new IllegalSetupProgressException(SetupProgress.PRIMING_FINISHED, podStateManager.getSetupProgress()); } From 2a731272022452de7f232a9b2b4487972263fd1b Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Sat, 8 Aug 2020 18:52:49 +0200 Subject: [PATCH 07/17] Small code improvements for PodStateManager --- .../omnipod/driver/comm/AapsOmnipodManager.java | 5 +---- .../omnipod/service/RileyLinkOmnipodService.java | 2 +- .../plugins/pump/omnipod/util/OmnipodConst.java | 1 - .../plugins/pump/omnipod/util/OmnipodUtil.java | 13 +++++++++++-- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java index 928157f06b..d5ac74c01d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java @@ -128,11 +128,8 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface podStateManager.setStateChangedHandler(manager -> { // Handle pod state changes - // FIXME only set once (?) (before instantiating AapsOmnipodManager) - // Maybe not, it seems to not only set something, but also fire an event - omnipodUtil.setPodStateManager(manager); - updatePumpStatus(manager); + omnipodUtil.notifyDeviceStatusChanged(); }); delegate = new OmnipodManager(aapsLogger, sp, communicationService, podStateManager); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java index a84996dc53..b38f7f40fb 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java @@ -122,8 +122,8 @@ public class RileyLinkOmnipodService extends RileyLinkService { omnipodUIComm = new OmnipodUIComm(injector, aapsLogger, omnipodUtil, omnipodUIPostprocessor, aapsOmnipodManager); } else { - aapsOmnipodManager = instance; omnipodUtil.setPodStateManager(instance.getPodStateManager()); + aapsOmnipodManager = instance; } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodConst.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodConst.java index d12fbd31df..f7b78250c3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodConst.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodConst.java @@ -14,7 +14,6 @@ public class OmnipodConst { public class Prefs { public static final String PodState = Prefix + "pod_state"; - public static final String NextPodAddress = Prefix + "next_pod_address"; public static final int BeepBasalEnabled = R.string.key_omnipod_beep_basal_enabled; public static final int BeepBolusEnabled = R.string.key_omnipod_beep_bolus_enabled; public static final int BeepSMBEnabled = R.string.key_omnipod_beep_smb_enabled; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodUtil.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodUtil.java index c008cee6e9..22e562bbc4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodUtil.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodUtil.java @@ -138,10 +138,16 @@ public class OmnipodUtil { return gsonBuilder.create(); } - public void setPodStateManager(PodStateManager podStateManager) { + if (podStateManager == null) { + throw new IllegalArgumentException("Pod state manager can not be null"); + } omnipodPumpStatus.podStateManager = podStateManager; - rxBus.send(new EventOmnipodDeviceStatusChange(podStateManager)); + notifyDeviceStatusChanged(); + } + + public void notifyDeviceStatusChanged() { + rxBus.send(new EventOmnipodDeviceStatusChange(omnipodPumpStatus.podStateManager)); } @@ -166,6 +172,9 @@ public class OmnipodUtil { public PodStateManager getPodStateManager() { + if (omnipodPumpStatus.podStateManager == null) { + throw new IllegalStateException("Pod state manager is null"); + } return omnipodPumpStatus.podStateManager; } From 10cde3e7448691cc4b274712a6514b6671aabfda Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Sat, 8 Aug 2020 19:05:36 +0200 Subject: [PATCH 08/17] More improvements for PodStateManager --- .../pump/omnipod/OmnipodPumpPlugin.java | 32 +++++++++---------- .../omnipod/dialogs/PodManagementActivity.kt | 10 +++--- .../driver/comm/AapsPodStateManager.java | 2 ++ .../pump/omnipod/util/OmnipodUtil.java | 1 + 4 files changed, 23 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java index 46040c78ab..2d6bd2306a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java @@ -487,17 +487,17 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump public boolean isSuspended() { return (omnipodUtil.getDriverState() == OmnipodDriverState.Initalized_NoPod) || - (omnipodUtil.getPodStateManager() != null && omnipodUtil.getPodStateManager().hasState() && omnipodUtil.getPodStateManager().isSuspended()); + (omnipodUtil.getPodStateManager().hasState() && omnipodUtil.getPodStateManager().isSuspended()); // return (pumpStatusLocal != null && !pumpStatusLocal.podAvailable) || -// (OmnipodUtil.getPodStateManager() != null && omnipodUtil.getPodStateManager().hasState() && OmnipodUtil.getPodStateManager().isSuspended()); +// (omnipodUtil.getPodStateManager().hasState() && OmnipodUtil.getPodStateManager().isSuspended()); // // TODO ddd // return (OmnipodUtil.getDriverState() == OmnipodDriverState.Initalized_NoPod) || -// (OmnipodUtil.getPodStateManager() != null && omnipodUtil.getPodStateManager().hasState() && OmnipodUtil.getPodStateManager().isSuspended()); +// (omnipodUtil.getPodStateManager().hasState() && OmnipodUtil.getPodStateManager().isSuspended()); // // return (pumpStatusLocal != null && !pumpStatusLocal.podAvailable) || -// (OmnipodUtil.getPodStateManager() != null && omnipodUtil.getPodStateManager().hasState() && OmnipodUtil.getPodStateManager().isSuspended()); +// (omnipodUtil.getPodStateManager().hasState() && OmnipodUtil.getPodStateManager().isSuspended()); } @Override @@ -579,6 +579,7 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump //getPodPumpStatusObject().driverState = OmnipodDriverState.Initalized_PodAvailable; //driverState = OmnipodDriverState.Initalized_PodAvailable; + // FIXME this does not seem to make sense omnipodUtil.setDriverState(OmnipodDriverState.Initalized_PodAttached); // we would probably need to read Basal Profile here too } @@ -621,21 +622,20 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump setRefreshButtonEnabled(false); - PodStateManager podStateManager = omnipodUtil.getPodStateManager(); - - if (podStateManager != null) { - if (!isRefresh) { - pumpState = PumpDriverState.Initialized; - } - - // TODO handle if session state too old - getPodPumpStatus(); - - } else { - aapsLogger.error(LTag.PUMP, "No PodStateManager found"); + try { + PodStateManager podStateManager = omnipodUtil.getPodStateManager(); + } catch(Exception ex) { omnipodUtil.setDriverState(OmnipodDriverState.Initalized_NoPod); + throw ex; } + if (!isRefresh) { + pumpState = PumpDriverState.Initialized; + } + + // TODO handle if pod state too old + getPodPumpStatus(); + finishAction("Omnipod Pump"); // if (!sentIdToFirebase) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/PodManagementActivity.kt b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/PodManagementActivity.kt index 012e7c6386..c80fa1462b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/PodManagementActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/PodManagementActivity.kt @@ -99,7 +99,7 @@ class PodManagementActivity : NoSplashAppCompatActivity() { wizardPagerContext.clearContext() wizardPagerContext.pagerSettings = pagerSettings val podStateManager = omnipodUtil.getPodStateManager() - val isFullInit = podStateManager == null || !podStateManager.isPaired || podStateManager.setupProgress.isBefore(SetupProgress.PRIMING_FINISHED) + val isFullInit = !podStateManager.isPaired || podStateManager.setupProgress.isBefore(SetupProgress.PRIMING_FINISHED) if (isFullInit) { wizardPagerContext.wizardModel = FullInitPodWizardModel(applicationContext) } else { @@ -150,13 +150,11 @@ class PodManagementActivity : NoSplashAppCompatActivity() { } fun refreshButtons() { - initpod_init_pod.isEnabled = omnipodUtil.podStateManager == null || !omnipodUtil.podStateManager.isPaired() || + initpod_init_pod.isEnabled = !omnipodUtil.podStateManager.isPaired() || omnipodUtil.getPodStateManager().getSetupProgress().isBefore(SetupProgress.COMPLETED) - val isPodSessionActive = omnipodUtil.podStateManager != null && omnipodUtil.podStateManager.hasState() - - initpod_remove_pod.isEnabled = isPodSessionActive && omnipodUtil.podStateManager.isPaired - initpod_reset_pod.isEnabled = isPodSessionActive + initpod_remove_pod.isEnabled = omnipodUtil.podStateManager.hasState() && omnipodUtil.podStateManager.isPaired + initpod_reset_pod.isEnabled = omnipodUtil.podStateManager.hasState() if (omnipodUtil.getDriverState() == OmnipodDriverState.NotInitalized) { // if rileylink is not running we disable all operations diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java index 3e278f03a8..49904a0c60 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java @@ -56,6 +56,7 @@ public class AapsPodStateManager implements PodStateManager { @Override public void removeState() { this.podState = null; persistPodState(); + notifyPodStateChanged(); } @Override @@ -65,6 +66,7 @@ public class AapsPodStateManager implements PodStateManager { } podState = new PodState(address); persistPodState(); + notifyPodStateChanged(); } @Override public boolean isPaired() { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodUtil.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodUtil.java index 22e562bbc4..c88dd5dcdd 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodUtil.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodUtil.java @@ -173,6 +173,7 @@ public class OmnipodUtil { public PodStateManager getPodStateManager() { if (omnipodPumpStatus.podStateManager == null) { + aapsLogger.error("OmnipodUtil.getPodStateManager was called, but podStateManager is null"); throw new IllegalStateException("Pod state manager is null"); } return omnipodPumpStatus.podStateManager; From 31938547a59bfc7f052d4963609bdef1eb6bd92a Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Sat, 8 Aug 2020 21:38:08 +0200 Subject: [PATCH 09/17] Fixes for PodStateManager --- .../plugins/pump/omnipod/comm/action/AssignAddressAction.java | 1 - .../plugins/pump/omnipod/driver/comm/AapsPodStateManager.java | 4 ++-- .../plugins/pump/omnipod/service/RileyLinkOmnipodService.java | 1 + 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/AssignAddressAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/AssignAddressAction.java index 91590185e0..0637a75872 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/AssignAddressAction.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/AssignAddressAction.java @@ -49,7 +49,6 @@ public class AssignAddressAction implements OmnipodAction { podStateManager.setPairingParameters(assignAddressResponse.getLot(), assignAddressResponse.getTid(), // assignAddressResponse.getPiVersion(), assignAddressResponse.getPmVersion(), DateTimeZone.getDefault()); - podStateManager.setMessageNumber(0x00); return assignAddressResponse; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java index 49904a0c60..8d5feea0a5 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java @@ -128,11 +128,11 @@ public class AapsPodStateManager implements PodStateManager { } @Override public void increaseMessageNumber() { - setAndStore(() -> podState.setMessageNumber(podState.getMessageNumber() + 1)); + setAndStore(() -> podState.setMessageNumber((podState.getMessageNumber() + 1) & 0b1111)); } @Override public void increasePacketNumber() { - setAndStore(() -> podState.setPacketNumber(podState.getPacketNumber() + 1)); + setAndStore(() -> podState.setPacketNumber((podState.getPacketNumber() + 1) & 0b11111)); } @Override public synchronized void resyncNonce(int syncWord, int sentNonce, int sequenceNumber) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java index b38f7f40fb..8100f2afff 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java @@ -125,6 +125,7 @@ public class RileyLinkOmnipodService extends RileyLinkService { omnipodUtil.setPodStateManager(instance.getPodStateManager()); aapsOmnipodManager = instance; } + omnipodUtil.notifyDeviceStatusChanged(); } From e5274e2d3a3a79bb4f24ad68a3ae3f338e7795b1 Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Sun, 9 Aug 2020 13:24:48 +0200 Subject: [PATCH 10/17] - Extract abstract class for PodStateManager on driver level - Remove PodStateChangedHandler - Add new fields to PodState - Add Lot, Tid and Firmware Version in Pod tab - Various small improvements - Add some FIXMEs --- .../dependencyInjection/OmnipodModule.kt | 18 +- .../plugins/pump/omnipod/OmnipodFragment.kt | 42 +- .../comm/OmnipodCommunicationManager.java | 8 + .../pump/omnipod/comm/OmnipodManager.java | 10 +- .../comm/action/CancelDeliveryAction.java | 6 +- .../comm/action/SetTempBasalAction.java | 6 +- .../plugins/pump/omnipod/defs/AlertSet.java | 6 +- .../OmnipodCommunicationManagerInterface.java | 4 - .../defs/state/PodStateChangedHandler.java | 6 - .../omnipod/defs/state/PodStateManager.java | 736 ++++++++++++++++-- .../driver/comm/AapsOmnipodManager.java | 125 --- .../driver/comm/AapsPodStateManager.java | 717 ++++------------- .../service/RileyLinkOmnipodService.java | 2 +- .../pump/omnipod/util/OmnipodConst.java | 1 + .../comm/OmnipodDashCommunicationManager.java | 5 - app/src/main/res/layout/omnipod_fragment.xml | 178 ++++- app/src/main/res/values/strings.xml | 3 + 17 files changed, 1039 insertions(+), 834 deletions(-) delete mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateChangedHandler.java diff --git a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/OmnipodModule.kt b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/OmnipodModule.kt index e458957fb9..dc8f3ddc77 100644 --- a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/OmnipodModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/OmnipodModule.kt @@ -11,7 +11,6 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.initpod.In import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.pages.InitPodRefreshAction import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.pages.PodInfoFragment import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.removepod.RemoveActionFragment -import info.nightscout.androidaps.plugins.pump.omnipod.driver.comm.AapsOmnipodManager import info.nightscout.androidaps.plugins.pump.omnipod.driver.comm.AapsPodStateManager import info.nightscout.androidaps.plugins.pump.omnipod.driver.ui.OmnipodUITask @@ -20,24 +19,25 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.ui.OmnipodUITask abstract class OmnipodModule { // Activities - @ContributesAndroidInjector abstract fun contributesPodManagementActivity(): PodManagementActivity + @ContributesAndroidInjector + abstract fun contributesPodManagementActivity(): PodManagementActivity @ContributesAndroidInjector abstract fun contributesPodHistoryActivity(): PodHistoryActivity // Fragments - @ContributesAndroidInjector abstract fun initActionFragment() : InitActionFragment - @ContributesAndroidInjector abstract fun removeActionFragment() : RemoveActionFragment - @ContributesAndroidInjector abstract fun podInfoFragment() : PodInfoFragment + @ContributesAndroidInjector abstract fun initActionFragment(): InitActionFragment + @ContributesAndroidInjector abstract fun removeActionFragment(): RemoveActionFragment + @ContributesAndroidInjector abstract fun podInfoFragment(): PodInfoFragment // Service - @ContributesAndroidInjector abstract fun omnipodCommunicationManagerProvider(): OmnipodCommunicationManager - @ContributesAndroidInjector abstract fun aapsOmnipodManagerProvider(): AapsOmnipodManager + @ContributesAndroidInjector + abstract fun omnipodCommunicationManagerProvider(): OmnipodCommunicationManager // Data @ContributesAndroidInjector abstract fun omnipodUITaskProvider(): OmnipodUITask @ContributesAndroidInjector abstract fun initPodRefreshAction(): InitPodRefreshAction @ContributesAndroidInjector abstract fun podStateManager(): PodStateManager - @ContributesAndroidInjector abstract fun initPodTask() : InitPodTask + @ContributesAndroidInjector abstract fun initPodTask(): InitPodTask - @ContributesAndroidInjector abstract fun initAapsPodStateManager() : AapsPodStateManager + @ContributesAndroidInjector abstract fun initAapsPodStateManager(): AapsPodStateManager } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt index 27b7558d62..12e591cb23 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt @@ -207,16 +207,10 @@ class OmnipodFragment : DaggerFragment() { } @Synchronized - private fun setDeviceStatus(event : EventOmnipodDeviceStatusChange) { - - + private fun setDeviceStatus(event: EventOmnipodDeviceStatusChange) { } - - - - @Synchronized private fun setDeviceStatus() { //val omnipodPumpStatus: OmnipodPumpStatus = OmnipodUtil.getPumpStatus() @@ -250,20 +244,31 @@ class OmnipodFragment : DaggerFragment() { aapsLogger.info(LTag.PUMP, "getDriverState: [driverState={}]", driverState) + // FIXME for displaying pod info, we should look at PodStateManager instead of this driverState, + // because that way, we can also show the Pod info when the RL isn't initialized yet if (driverState == OmnipodDriverState.NotInitalized) { omnipod_pod_address.text = resourceHelper.gs(R.string.omnipod_pod_name_no_info) + omnipod_pod_lot.text = "-" + omnipod_pod_tid.text = "-" + omnipod_pod_fw_version.text = "-" omnipod_pod_expiry.text = "-" omnipod_pod_status.text = resourceHelper.gs(R.string.omnipod_pod_not_initalized) omnipodPumpStatus.podAvailable = false omnipodPumpStatus.podNumber == null } else if (driverState == OmnipodDriverState.Initalized_NoPod) { omnipod_pod_address.text = resourceHelper.gs(R.string.omnipod_pod_name_no_info) + omnipod_pod_lot.text = "-" + omnipod_pod_tid.text = "-" + omnipod_pod_fw_version.text = "-" omnipod_pod_expiry.text = "-" omnipod_pod_status.text = resourceHelper.gs(R.string.omnipod_pod_no_pod_connected) omnipodPumpStatus.podAvailable = false omnipodPumpStatus.podNumber == null } else if (driverState == OmnipodDriverState.Initalized_PodInitializing) { omnipod_pod_address.text = omnipodPumpStatus.podStateManager.address.toString() + omnipod_pod_lot.text = "-" + omnipod_pod_tid.text = "-" + omnipod_pod_fw_version.text = "-" omnipod_pod_expiry.text = "-" omnipod_pod_status.text = resourceHelper.gs(R.string.omnipod_pod_status_initalizing) + " (" + omnipodPumpStatus.podStateManager.getSetupProgress().name + ")" omnipodPumpStatus.podAvailable = false @@ -272,16 +277,24 @@ class OmnipodFragment : DaggerFragment() { omnipodPumpStatus.podLotNumber = "" + omnipodPumpStatus.podStateManager.lot omnipodPumpStatus.podAvailable = true omnipod_pod_address.text = omnipodPumpStatus.podStateManager.address.toString() + omnipod_pod_lot.text = if (omnipodPumpStatus.podStateManager.lot == null) "" else omnipodPumpStatus.podStateManager.lot.toString() + omnipod_pod_tid.text = if (omnipodPumpStatus.podStateManager.tid == null) "" else omnipodPumpStatus.podStateManager.tid.toString() + if (omnipodPumpStatus.podStateManager.pmVersion == null || omnipodPumpStatus.podStateManager.piVersion == null) { + omnipod_pod_fw_version.text = "" + } else { + omnipod_pod_fw_version.text = omnipodPumpStatus.podStateManager.pmVersion.toString() + " / " + omnipodPumpStatus.podStateManager.piVersion.toString() + } omnipod_pod_expiry.text = omnipodPumpStatus.podStateManager.expiryDateAsString omnipodPumpStatus.podNumber = omnipodPumpStatus.podStateManager.address.toString() var podDeviceState = omnipodPumpStatus.podDeviceState - var stateText : String? + var stateText: String? + // FIXME this PodDeviceState doesn't make much sense. We should use info from PodStateManager when (podDeviceState) { null, - PodDeviceState.Sleeping -> stateText = "{fa-bed} " // + pumpStatus.pumpDeviceState.name()); + PodDeviceState.Sleeping -> stateText = "{fa-bed} " // + pumpStatus.pumpDeviceState.name()); PodDeviceState.NeverContacted, PodDeviceState.WakingUp, PodDeviceState.PumpUnreachable, @@ -289,7 +302,7 @@ class OmnipodFragment : DaggerFragment() { PodDeviceState.TimeoutWhenCommunicating, PodDeviceState.InvalidConfiguration -> stateText = " " + resourceHelper.gs(podDeviceState.resourceId) - PodDeviceState.Active -> { + PodDeviceState.Active -> { stateText = resourceHelper.gs(R.string.omnipod_pod_status_active) // val cmd = OmnipodUtil.getCurrentCommand() // if (cmd == null) @@ -308,18 +321,19 @@ class OmnipodFragment : DaggerFragment() { // } // } } - else -> { + + else -> { aapsLogger.warn(LTag.PUMP, "Unknown pump state: " + omnipodPumpStatus.podDeviceState) stateText = resourceHelper.gs(R.string.omnipod_pod_status_unknown) } } - if (SetupProgress.COMPLETED.equals(omnipodPumpStatus.podStateManager.getSetupProgress())) { - if(omnipodPumpStatus.podStateManager.lastDeliveryStatus != null) { + if (omnipodPumpStatus.podStateManager.isSetupCompleted) { + if (omnipodPumpStatus.podStateManager.lastDeliveryStatus != null) { stateText += " (last delivery status: " + omnipodPumpStatus.podStateManager.lastDeliveryStatus.name + ")" } } else { - if(omnipodPumpStatus.podStateManager.setupProgress != null) { + if (omnipodPumpStatus.podStateManager.isPaired) { stateText += " (setup progress: " + omnipodPumpStatus.podStateManager.setupProgress.name + ")" } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodCommunicationManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodCommunicationManager.java index 6968532adb..7c9a96c0b4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodCommunicationManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodCommunicationManager.java @@ -1,5 +1,7 @@ package info.nightscout.androidaps.plugins.pump.omnipod.comm; +import org.joda.time.DateTime; + import java.util.Collections; import java.util.List; @@ -144,6 +146,7 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager { } if (responseClass.isInstance(responseMessageBlock)) { + podStateManager.setLastSuccessfulCommunication(DateTime.now()); return (T) responseMessageBlock; } else { if (responseMessageBlock.getType() == MessageBlockType.ERROR_RESPONSE) { @@ -153,21 +156,26 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager { if (automaticallyResyncNonce) { message.resyncNonce(podStateManager.getCurrentNonce()); } else { + podStateManager.setLastFailedCommunication(DateTime.now()); throw new NonceOutOfSyncException(); } } else { + podStateManager.setLastFailedCommunication(DateTime.now()); throw new PodReturnedErrorResponseException(error); } } else if (responseMessageBlock.getType() == MessageBlockType.POD_INFO_RESPONSE && ((PodInfoResponse) responseMessageBlock).getSubType() == PodInfoType.FAULT_EVENT) { PodInfoFaultEvent faultEvent = ((PodInfoResponse) responseMessageBlock).getPodInfo(); podStateManager.setFaultEvent(faultEvent); + podStateManager.setLastFailedCommunication(DateTime.now()); throw new PodFaultException(faultEvent); } else { + podStateManager.setLastFailedCommunication(DateTime.now()); throw new IllegalResponseException(responseClass.getSimpleName(), responseMessageBlock.getType()); } } } + podStateManager.setLastFailedCommunication(DateTime.now()); throw new NonceResyncException(); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodManager.java index 3f3974bb21..3de30a1845 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodManager.java @@ -208,9 +208,10 @@ public class OmnipodManager { } try { - return executeAndVerify(() -> communicationService.executeAction(new SetTempBasalAction( + StatusResponse statusResponse = executeAndVerify(() -> communicationService.executeAction(new SetTempBasalAction( podStateManager, rate, duration, acknowledgementBeep, completionBeep))); + return statusResponse; } catch (OmnipodException ex) { // Treat all exceptions as uncertain failures, because all delivery has been suspended here. // Setting this to an uncertain failure will enable for the user to get an appropriate warning @@ -266,6 +267,7 @@ public class OmnipodManager { } DateTime startDate = DateTime.now().minus(OmnipodConst.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION); + podStateManager.setLastBolus(startDate, units); CompositeDisposable disposables = new CompositeDisposable(); Duration bolusDuration = calculateBolusDuration(units, OmnipodConst.POD_BOLUS_DELIVERY_RATE); @@ -352,8 +354,10 @@ public class OmnipodManager { private void discardActiveBolusData(double unitsNotDelivered) { synchronized (bolusDataMutex) { + double unitsDelivered = activeBolusData.getUnits() - unitsNotDelivered; + podStateManager.setLastBolus(activeBolusData.getStartDate(), unitsDelivered); activeBolusData.getDisposables().dispose(); - activeBolusData.getBolusCompletionSubject().onSuccess(new BolusDeliveryResult(activeBolusData.getUnits() - unitsNotDelivered)); + activeBolusData.getBolusCompletionSubject().onSuccess(new BolusDeliveryResult(unitsDelivered)); activeBolusData = null; } } @@ -446,7 +450,7 @@ public class OmnipodManager { } public boolean isReadyForDelivery() { - return podStateManager.isPaired() && podStateManager.getSetupProgress() == SetupProgress.COMPLETED; + return podStateManager.isSetupCompleted(); } public boolean hasActiveBolus() { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/CancelDeliveryAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/CancelDeliveryAction.java index 9df030fec5..c29135a24f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/CancelDeliveryAction.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/CancelDeliveryAction.java @@ -50,7 +50,11 @@ public class CancelDeliveryAction implements OmnipodAction { acknowledgementBeep && deliveryTypes.size() == 1 ? BeepType.BEEP : BeepType.NO_BEEP, deliveryTypes)); } - return communicationService.exchangeMessages(StatusResponse.class, podStateManager, + StatusResponse statusResponse = communicationService.exchangeMessages(StatusResponse.class, podStateManager, new OmnipodMessage(podStateManager.getAddress(), messageBlocks, podStateManager.getMessageNumber())); + if (deliveryTypes.contains(DeliveryType.TEMP_BASAL)) { + podStateManager.setLastTempBasal(null, null, null); + } + return statusResponse; } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetTempBasalAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetTempBasalAction.java index f316ece733..0610256d81 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetTempBasalAction.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetTempBasalAction.java @@ -1,5 +1,6 @@ package info.nightscout.androidaps.plugins.pump.omnipod.comm.action; +import org.joda.time.DateTime; import org.joda.time.Duration; import java.util.Arrays; @@ -13,6 +14,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.SetI import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.TempBasalExtraCommand; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; public class SetTempBasalAction implements OmnipodAction { private final PodStateManager podStateManager; @@ -43,6 +45,8 @@ public class SetTempBasalAction implements OmnipodAction { new TempBasalExtraCommand(rate, duration, acknowledgementBeep, completionBeep, Duration.ZERO)); OmnipodMessage message = new OmnipodMessage(podStateManager.getAddress(), messageBlocks, podStateManager.getMessageNumber()); - return communicationService.exchangeMessages(StatusResponse.class, podStateManager, message); + StatusResponse statusResponse = communicationService.exchangeMessages(StatusResponse.class, podStateManager, message); + podStateManager.setLastTempBasal(new DateTime().minus(OmnipodConst.AVERAGE_TEMP_BASAL_COMMAND_COMMUNICATION_DURATION), rate, duration); + return statusResponse; } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/AlertSet.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/AlertSet.java index 9d65d7d5aa..91590e2f12 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/AlertSet.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/AlertSet.java @@ -15,8 +15,12 @@ public class AlertSet { } } + public AlertSet(AlertSet alertSet) { + this(alertSet == null ? new ArrayList<>() : alertSet.getAlertSlots()); + } + public AlertSet(List alertSlots) { - this.alertSlots = alertSlots; + this.alertSlots = alertSlots == null ? new ArrayList<>() : new ArrayList<>(alertSlots); } public List getAlertSlots() { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/OmnipodCommunicationManagerInterface.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/OmnipodCommunicationManagerInterface.java index 3999cd2923..d345a3c385 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/OmnipodCommunicationManagerInterface.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/OmnipodCommunicationManagerInterface.java @@ -71,9 +71,5 @@ public interface OmnipodCommunicationManagerInterface { */ PumpEnactResult setTime(); - - void setPumpStatus(OmnipodPumpStatus pumpStatusLocal); - - PodInfoRecentPulseLog readPulseLog(); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateChangedHandler.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateChangedHandler.java deleted file mode 100644 index c1171b498e..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateChangedHandler.java +++ /dev/null @@ -1,6 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs.state; - -@FunctionalInterface -public interface PodStateChangedHandler { - void handle(PodStateManager podStateManager); -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateManager.java index 009503bad1..1956c696ac 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateManager.java @@ -1,9 +1,23 @@ package info.nightscout.androidaps.plugins.pump.omnipod.defs.state; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonPrimitive; +import com.google.gson.JsonSerializer; + +import org.apache.commons.lang3.StringUtils; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.joda.time.Duration; +import org.joda.time.format.ISODateTimeFormat; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import info.nightscout.androidaps.logging.AAPSLogger; +import info.nightscout.androidaps.logging.LTag; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoFaultEvent; import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSet; @@ -13,92 +27,726 @@ import info.nightscout.androidaps.plugins.pump.omnipod.defs.DeliveryStatus; import info.nightscout.androidaps.plugins.pump.omnipod.defs.FirmwareVersion; import info.nightscout.androidaps.plugins.pump.omnipod.defs.SetupProgress; import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BasalSchedule; +import info.nightscout.androidaps.plugins.pump.omnipod.util.OmniCRC; +import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; +import info.nightscout.androidaps.utils.DateUtil; -public interface PodStateManager { +public abstract class PodStateManager { - boolean hasState(); + private final AAPSLogger aapsLogger; + private final Gson gsonInstance; + private PodState podState; - void removeState(); + public PodStateManager(AAPSLogger aapsLogger) { + this.aapsLogger = aapsLogger; + this.gsonInstance = createGson(); + } - void initState(int address); + public final boolean hasState() { + return podState != null; + } - boolean isPaired(); + public final void removeState() { + this.podState = null; + storePodState(); + notifyPodStateChanged(); + } - void setPairingParameters(int lot, int tid, FirmwareVersion piVersion, FirmwareVersion pmVersion, DateTimeZone timeZone); + public final void initState(int address) { + if (hasState()) { + throw new IllegalStateException("Can not init a new pod state: podState <> null"); + } + podState = new PodState(address); + storePodState(); + notifyPodStateChanged(); + } - int getAddress(); + public final boolean isPaired() { + return hasState() // + && podState.getLot() != null && podState.getTid() != null // + && podState.getPiVersion() != null && podState.getPmVersion() != null // + && podState.getTimeZone() != null // + && podState.getSetupProgress() != null; + } - int getMessageNumber(); + public final boolean isSetupCompleted() { + return isPaired() && SetupProgress.COMPLETED.equals(podState.getSetupProgress()); + } - void setMessageNumber(int messageNumber); + public final void setPairingParameters(int lot, int tid, FirmwareVersion piVersion, FirmwareVersion pmVersion, DateTimeZone timeZone) { + if (!hasState()) { + throw new IllegalStateException("Cannot set pairing parameters: podState is null"); + } + if (isPaired()) { + throw new IllegalStateException("Cannot set pairing parameters: pairing parameters have already been set"); + } + if (piVersion == null) { + throw new IllegalArgumentException("Cannot set pairing parameters: piVersion can not be null"); + } + if (pmVersion == null) { + throw new IllegalArgumentException("Cannot set pairing parameters: pmVersion can not be null"); + } + if (timeZone == null) { + throw new IllegalArgumentException("Cannot set pairing parameters: timeZone can not be null"); + } - int getPacketNumber(); + setAndStore(() -> { + podState.setLot(lot); + podState.setTid(tid); + podState.setPiVersion(piVersion); + podState.setPmVersion(pmVersion); + podState.setTimeZone(timeZone); + podState.setNonceState(new NonceState(lot, tid)); + podState.setSetupProgress(SetupProgress.ADDRESS_ASSIGNED); + podState.getConfiguredAlerts().put(AlertSlot.SLOT7, AlertType.FINISH_SETUP_REMINDER); + }); + } - void setPacketNumber(int packetNumber); + public final int getAddress() { + return getSafe(() -> podState.getAddress()); + } - void increaseMessageNumber(); + public final int getMessageNumber() { + return getSafe(() -> podState.getMessageNumber()); + } - void increasePacketNumber(); + public final void setMessageNumber(int messageNumber) { + setAndStore(() -> podState.setMessageNumber(messageNumber)); + } - void resyncNonce(int syncWord, int sentNonce, int sequenceNumber); + public final int getPacketNumber() { + return getSafe(() -> podState.getPacketNumber()); + } - int getCurrentNonce(); + public final void setPacketNumber(int packetNumber) { + setAndStore(() -> podState.setPacketNumber(packetNumber)); + } - void advanceToNextNonce(); + public final void increaseMessageNumber() { + setAndStore(() -> podState.setMessageNumber((podState.getMessageNumber() + 1) & 0b1111)); + } - boolean hasFaultEvent(); + public final void increasePacketNumber() { + setAndStore(() -> podState.setPacketNumber((podState.getPacketNumber() + 1) & 0b11111)); + } - PodInfoFaultEvent getFaultEvent(); + public final synchronized void resyncNonce(int syncWord, int sentNonce, int sequenceNumber) { + if (!isPaired()) { + throw new IllegalStateException("Cannot resync nonce: Pod is not paired yet"); + } - void setFaultEvent(PodInfoFaultEvent faultEvent); + int sum = (sentNonce & 0xFFFF) + + OmniCRC.crc16lookup[sequenceNumber] + + (podState.getLot() & 0xFFFF) + + (podState.getTid() & 0xFFFF); + int seed = ((sum & 0xFFFF) ^ syncWord); + NonceState nonceState = new NonceState(podState.getLot(), podState.getTid(), (byte) (seed & 0xFF)); - AlertType getConfiguredAlertType(AlertSlot alertSlot); + setAndStore(() -> podState.setNonceState(nonceState)); + } - void putConfiguredAlert(AlertSlot alertSlot, AlertType alertType); + public final synchronized int getCurrentNonce() { + if (!isPaired()) { + throw new IllegalStateException("Cannot get current nonce: Pod is not paired yet"); + } + return podState.getNonceState().getCurrentNonce(); + } - void removeConfiguredAlert(AlertSlot alertSlot); + public final synchronized void advanceToNextNonce() { + if (!isPaired()) { + throw new IllegalStateException("Cannot advance to next nonce: Pod is not paired yet"); + } + setAndStore(() -> podState.getNonceState().advanceToNextNonce()); + } - boolean hasActiveAlerts(); + public final DateTime getLastSuccessfulCommunication() { + return getSafe(() -> podState.getLastSuccessfulCommunication()); + } - AlertSet getActiveAlerts(); + public final void setLastSuccessfulCommunication(DateTime dateTime) { + setAndStore(() -> podState.setLastSuccessfulCommunication(dateTime)); + } - Integer getLot(); + public final DateTime getLastFailedCommunication() { + return getSafe(() -> podState.getLastFailedCommunication()); + } - Integer getTid(); + public final void setLastFailedCommunication(DateTime dateTime) { + setAndStore(() -> podState.setLastFailedCommunication(dateTime)); + } - FirmwareVersion getPiVersion(); + public final boolean hasFaultEvent() { + return getSafe(() -> podState.getFaultEvent()) != null; + } - FirmwareVersion getPmVersion(); + public final PodInfoFaultEvent getFaultEvent() { + return getSafe(() -> podState.getFaultEvent()); + } - DateTimeZone getTimeZone(); + public final void setFaultEvent(PodInfoFaultEvent faultEvent) { + setAndStore(() -> podState.setFaultEvent(faultEvent)); + } - void setTimeZone(DateTimeZone timeZone); + public final AlertType getConfiguredAlertType(AlertSlot alertSlot) { + return getSafe(() -> podState.getConfiguredAlerts().get(alertSlot)); + } - DateTime getTime(); + public final void putConfiguredAlert(AlertSlot alertSlot, AlertType alertType) { + setAndStore(() -> podState.getConfiguredAlerts().put(alertSlot, alertType)); + } - DateTime getActivatedAt(); + public final void removeConfiguredAlert(AlertSlot alertSlot) { + setAndStore(() -> podState.getConfiguredAlerts().remove(alertSlot)); + } - DateTime getExpiresAt(); + public final boolean hasActiveAlerts() { + AlertSet activeAlerts = podState.getActiveAlerts(); + return activeAlerts != null && activeAlerts.size() > 0; + } - String getExpiryDateAsString(); + public final AlertSet getActiveAlerts() { + return new AlertSet(getSafe(() -> podState.getActiveAlerts())); + } - SetupProgress getSetupProgress(); + public final Integer getLot() { + return getSafe(() -> podState.getLot()); + } - void setSetupProgress(SetupProgress setupProgress); + public final Integer getTid() { + return getSafe(() -> podState.getTid()); + } - boolean isSuspended(); + public final FirmwareVersion getPiVersion() { + return getSafe(() -> podState.getPiVersion()); + } - Double getReservoirLevel(); + public final FirmwareVersion getPmVersion() { + return getSafe(() -> podState.getPmVersion()); + } - Duration getScheduleOffset(); + public final DateTimeZone getTimeZone() { + return getSafe(() -> podState.getTimeZone()); + } - BasalSchedule getBasalSchedule(); + public final void setTimeZone(DateTimeZone timeZone) { + if (timeZone == null) { + throw new IllegalArgumentException("Time zone can not be null"); + } + setAndStore(() -> podState.setTimeZone(timeZone)); + } - void setBasalSchedule(BasalSchedule basalSchedule); + public final DateTime getTime() { + DateTime now = DateTime.now(); + return now.withZone(getSafe(() -> podState.getTimeZone())); + } - DeliveryStatus getLastDeliveryStatus(); + public final DateTime getActivatedAt() { + DateTime activatedAt = getSafe(() -> podState.getActivatedAt()); + return activatedAt == null ? null : activatedAt.withZone(getSafe(() -> podState.getTimeZone())); + } - void updateFromStatusResponse(StatusResponse statusResponse); + public final DateTime getExpiresAt() { + DateTime expiresAt = getSafe(() -> podState.getExpiresAt()); + return expiresAt == null ? null : expiresAt.withZone(getSafe(() -> podState.getTimeZone())); + } - void setStateChangedHandler(PodStateChangedHandler handler); + // TODO doesn't belong here + public final String getExpiryDateAsString() { + DateTime expiresAt = getExpiresAt(); + return expiresAt == null ? "???" : DateUtil.dateAndTimeString(expiresAt.toDate()); + } + + public final SetupProgress getSetupProgress() { + return getSafe(() -> podState.getSetupProgress()); + } + + public final void setSetupProgress(SetupProgress setupProgress) { + if (setupProgress == null) { + throw new IllegalArgumentException("Setup progress can not be null"); + } + setAndStore(() -> podState.setSetupProgress(setupProgress)); + } + + public final boolean isSuspended() { + return getSafe(() -> podState.isSuspended()); + } + + public final Double getReservoirLevel() { + return getSafe(() -> podState.getReservoirLevel()); + } + + public final Duration getScheduleOffset() { + DateTime now = getTime(); + DateTime startOfDay = new DateTime(now.getYear(), now.getMonthOfYear(), now.getDayOfMonth(), + 0, 0, 0, getSafe(() -> podState.getTimeZone())); + return new Duration(startOfDay, now); + } + + public final BasalSchedule getBasalSchedule() { + return getSafe(() -> podState.getBasalSchedule()); + } + + public final void setBasalSchedule(BasalSchedule basalSchedule) { + setAndStore(() -> podState.setBasalSchedule(basalSchedule)); + } + + public final DateTime getLastBolusStartTime() { + return getSafe(() -> podState.getLastBolusStartTime()); + } + + public final Double getLastBolusAmount() { + return getSafe(() -> podState.getLastBolusAmount()); + } + + public final void setLastBolus(DateTime startTime, double amount) { + setAndStore(() -> { + podState.setLastBolusStartTime(startTime); + podState.setLastBolusAmount(amount); + }); + } + + public final DateTime getLastTempBasalStartTime() { + return getSafe(() -> podState.getLastTempBasalStartTime()); + } + + public final Double getLastTempBasalAmount() { + return getSafe(() -> podState.getLastTempBasalAmount()); + } + + public final Duration getLastTempBasalDuration() { + return getSafe(() -> podState.getLastTempBasalDuration()); + } + + public final void setLastTempBasal(DateTime startTime, Double amount, Duration duration) { + setAndStore(() -> { + podState.setLastTempBasalStartTime(startTime); + podState.setLastTempBasalAmount(amount); + podState.setLastTempBasalDuration(duration); + }); + } + + public final DeliveryStatus getLastDeliveryStatus() { + return getSafe(() -> podState.getLastDeliveryStatus()); + } + + public final void updateFromStatusResponse(StatusResponse statusResponse) { + if (!hasState()) { + throw new IllegalStateException("Cannot update from status response: podState is null"); + } + setAndStore(() -> { + if (podState.getActivatedAt() == null) { + DateTime activatedAtCalculated = getTime().minus(statusResponse.getTimeActive()); + podState.setActivatedAt(activatedAtCalculated); + } + DateTime expiresAt = podState.getExpiresAt(); + DateTime expiresAtCalculated = podState.getActivatedAt().plus(OmnipodConst.NOMINAL_POD_LIFE); + if (expiresAt == null || expiresAtCalculated.isBefore(expiresAt) || expiresAtCalculated.isAfter(expiresAt.plusMinutes(1))) { + podState.setExpiresAt(expiresAtCalculated); + } + + boolean newSuspendedState = statusResponse.getDeliveryStatus() == DeliveryStatus.SUSPENDED; + if (podState.isSuspended() != newSuspendedState) { + aapsLogger.info(LTag.PUMPCOMM, "Updating pod suspended state in updateFromStatusResponse. newSuspendedState={}, statusResponse={}", newSuspendedState, statusResponse.toString()); + podState.setSuspended(newSuspendedState); + } + podState.setActiveAlerts(statusResponse.getAlerts()); + podState.setLastDeliveryStatus(statusResponse.getDeliveryStatus()); + podState.setReservoirLevel(statusResponse.getReservoirLevel()); + }); + } + + private void setAndStore(Runnable runnable) { + if (!hasState()) { + throw new IllegalStateException("Cannot mutate PodState: podState is null"); + } + runnable.run(); + storePodState(); + notifyPodStateChanged(); + } + + private void storePodState() { + String podState = gsonInstance.toJson(this.podState); + aapsLogger.info(LTag.PUMP, "storePodState: storing podState: " + podState); + storePodState(podState); + } + + protected abstract void storePodState(String podState); + + protected abstract String readPodState(); + + // Should be called after initializing the object + public final void loadPodState() { + podState = null; + + String storedPodState = readPodState(); + + if (StringUtils.isEmpty(storedPodState)) { + aapsLogger.info(LTag.PUMP, "loadPodState: no Pod state was provided"); + } else { + aapsLogger.info(LTag.PUMP, "loadPodState: serialized Pod state was provided: " + storedPodState); + try { + podState = gsonInstance.fromJson(storedPodState, PodState.class); + } catch (Exception ex) { + aapsLogger.error(LTag.PUMP, "loadPodState: could not deserialize PodState: " + storedPodState, ex); + } + } + + notifyPodStateChanged(); + } + + protected abstract void notifyPodStateChanged(); + + // Not actually "safe" as it throws an Exception, but it prevents NPEs + private T getSafe(Supplier supplier) { + if (!hasState()) { + throw new IllegalStateException("Cannot read from PodState: podState is null"); + } + return supplier.get(); + } + + private static Gson createGson() { + GsonBuilder gsonBuilder = new GsonBuilder() + .registerTypeAdapter(DateTime.class, (JsonSerializer) (dateTime, typeOfSrc, context) -> + new JsonPrimitive(ISODateTimeFormat.dateTime().print(dateTime))) + .registerTypeAdapter(DateTime.class, (JsonDeserializer) (json, typeOfT, context) -> + ISODateTimeFormat.dateTime().parseDateTime(json.getAsString())) + .registerTypeAdapter(DateTimeZone.class, (JsonSerializer) (timeZone, typeOfSrc, context) -> + new JsonPrimitive(timeZone.getID())) + .registerTypeAdapter(DateTimeZone.class, (JsonDeserializer) (json, typeOfT, context) -> + DateTimeZone.forID(json.getAsString())); + + return gsonBuilder.create(); + } + + @Override public String toString() { + return "AapsPodStateManager{" + + "podState=" + podState + + '}'; + } + + private static final class PodState { + private final int address; + private Integer lot; + private Integer tid; + private FirmwareVersion piVersion; + private FirmwareVersion pmVersion; + private int packetNumber; + private int messageNumber; + private DateTime lastSuccessfulCommunication; + private DateTime lastFailedCommunication; + private DateTimeZone timeZone; + private DateTime activatedAt; + private DateTime expiresAt; + private PodInfoFaultEvent faultEvent; + private Double reservoirLevel; + private boolean suspended; + private NonceState nonceState; + private SetupProgress setupProgress; + private DeliveryStatus lastDeliveryStatus; + private AlertSet activeAlerts; + private BasalSchedule basalSchedule; + private DateTime lastBolusStartTime; + private Double lastBolusAmount; + private Double lastTempBasalAmount; + private DateTime lastTempBasalStartTime; + private Duration lastTempBasalDuration; + private final Map configuredAlerts = new HashMap<>(); + + private PodState(int address) { + this.address = address; + } + + int getAddress() { + return address; + } + + Integer getLot() { + return lot; + } + + void setLot(int lot) { + this.lot = lot; + } + + Integer getTid() { + return tid; + } + + void setTid(int tid) { + this.tid = tid; + } + + FirmwareVersion getPiVersion() { + return piVersion; + } + + void setPiVersion(FirmwareVersion piVersion) { + if (this.piVersion != null) { + throw new IllegalStateException("piVersion has already been set"); + } + if (piVersion == null) { + throw new IllegalArgumentException("piVersion can not be null"); + } + this.piVersion = piVersion; + } + + FirmwareVersion getPmVersion() { + return pmVersion; + } + + void setPmVersion(FirmwareVersion pmVersion) { + this.pmVersion = pmVersion; + } + + int getPacketNumber() { + return packetNumber; + } + + void setPacketNumber(int packetNumber) { + this.packetNumber = packetNumber; + } + + int getMessageNumber() { + return messageNumber; + } + + void setMessageNumber(int messageNumber) { + this.messageNumber = messageNumber; + } + + DateTime getLastSuccessfulCommunication() { + return lastSuccessfulCommunication; + } + + void setLastSuccessfulCommunication(DateTime lastSuccessfulCommunication) { + this.lastSuccessfulCommunication = lastSuccessfulCommunication; + } + + DateTime getLastFailedCommunication() { + return lastFailedCommunication; + } + + void setLastFailedCommunication(DateTime lastFailedCommunication) { + this.lastFailedCommunication = lastFailedCommunication; + } + + DateTimeZone getTimeZone() { + return timeZone; + } + + void setTimeZone(DateTimeZone timeZone) { + this.timeZone = timeZone; + } + + DateTime getActivatedAt() { + return activatedAt; + } + + void setActivatedAt(DateTime activatedAt) { + this.activatedAt = activatedAt; + } + + DateTime getExpiresAt() { + return expiresAt; + } + + void setExpiresAt(DateTime expiresAt) { + this.expiresAt = expiresAt; + } + + PodInfoFaultEvent getFaultEvent() { + return faultEvent; + } + + void setFaultEvent(PodInfoFaultEvent faultEvent) { + this.faultEvent = faultEvent; + } + + Double getReservoirLevel() { + return reservoirLevel; + } + + void setReservoirLevel(Double reservoirLevel) { + this.reservoirLevel = reservoirLevel; + } + + public boolean isSuspended() { + return suspended; + } + + void setSuspended(boolean suspended) { + this.suspended = suspended; + } + + NonceState getNonceState() { + return nonceState; + } + + void setNonceState(NonceState nonceState) { + this.nonceState = nonceState; + } + + public SetupProgress getSetupProgress() { + return setupProgress; + } + + void setSetupProgress(SetupProgress setupProgress) { + this.setupProgress = setupProgress; + } + + DeliveryStatus getLastDeliveryStatus() { + return lastDeliveryStatus; + } + + void setLastDeliveryStatus(DeliveryStatus lastDeliveryStatus) { + this.lastDeliveryStatus = lastDeliveryStatus; + } + + AlertSet getActiveAlerts() { + return activeAlerts; + } + + void setActiveAlerts(AlertSet activeAlerts) { + this.activeAlerts = activeAlerts; + } + + BasalSchedule getBasalSchedule() { + return basalSchedule; + } + + void setBasalSchedule(BasalSchedule basalSchedule) { + this.basalSchedule = basalSchedule; + } + + public DateTime getLastBolusStartTime() { + return lastBolusStartTime; + } + + void setLastBolusStartTime(DateTime lastBolusStartTime) { + this.lastBolusStartTime = lastBolusStartTime; + } + + Double getLastBolusAmount() { + return lastBolusAmount; + } + + void setLastBolusAmount(Double lastBolusAmount) { + this.lastBolusAmount = lastBolusAmount; + } + + Double getLastTempBasalAmount() { + return lastTempBasalAmount; + } + + void setLastTempBasalAmount(Double lastTempBasalAmount) { + this.lastTempBasalAmount = lastTempBasalAmount; + } + + DateTime getLastTempBasalStartTime() { + return lastTempBasalStartTime; + } + + void setLastTempBasalStartTime(DateTime lastTempBasalStartTime) { + this.lastTempBasalStartTime = lastTempBasalStartTime; + } + + Duration getLastTempBasalDuration() { + return lastTempBasalDuration; + } + + void setLastTempBasalDuration(Duration lastTempBasalDuration) { + this.lastTempBasalDuration = lastTempBasalDuration; + } + + Map getConfiguredAlerts() { + return configuredAlerts; + } + + @Override public String toString() { + return "PodState{" + + "address=" + address + + ", lot=" + lot + + ", tid=" + tid + + ", piVersion=" + piVersion + + ", pmVersion=" + pmVersion + + ", packetNumber=" + packetNumber + + ", messageNumber=" + messageNumber + + ", lastSuccessfulCommunication=" + lastSuccessfulCommunication + + ", lastFailedCommunication=" + lastFailedCommunication + + ", timeZone=" + timeZone + + ", activatedAt=" + activatedAt + + ", expiresAt=" + expiresAt + + ", faultEvent=" + faultEvent + + ", reservoirLevel=" + reservoirLevel + + ", suspended=" + suspended + + ", nonceState=" + nonceState + + ", setupProgress=" + setupProgress + + ", lastDeliveryStatus=" + lastDeliveryStatus + + ", activeAlerts=" + activeAlerts + + ", basalSchedule=" + basalSchedule + + ", lastBolusStartTime=" + lastBolusStartTime + + ", lastBolusAmount=" + lastBolusAmount + + ", lastTempBasalAmount=" + lastTempBasalAmount + + ", lastTempBasalStartTime=" + lastTempBasalStartTime + + ", lastTempBasalDuration=" + lastTempBasalDuration + + ", configuredAlerts=" + configuredAlerts + + '}'; + } + } + + private static class NonceState { + private final long[] table = new long[21]; + private int index; + + private NonceState(int lot, int tid) { + initializeTable(lot, tid, (byte) 0x00); + } + + private NonceState(int lot, int tid, byte seed) { + initializeTable(lot, tid, seed); + } + + private void initializeTable(int lot, int tid, byte seed) { + table[0] = (long) (lot & 0xFFFF) + 0x55543DC3L + (((long) (lot) & 0xFFFFFFFFL) >> 16); + table[0] = table[0] & 0xFFFFFFFFL; + table[1] = (tid & 0xFFFF) + 0xAAAAE44EL + (((long) (tid) & 0xFFFFFFFFL) >> 16); + table[1] = table[1] & 0xFFFFFFFFL; + index = 0; + table[0] += seed; + for (int i = 0; i < 16; i++) { + table[2 + i] = generateEntry(); + } + index = (int) ((table[0] + table[1]) & 0X0F); + } + + private int generateEntry() { + table[0] = (((table[0] >> 16) + (table[0] & 0xFFFF) * 0x5D7FL) & 0xFFFFFFFFL); + table[1] = (((table[1] >> 16) + (table[1] & 0xFFFF) * 0x8CA0L) & 0xFFFFFFFFL); + return (int) ((table[1] + (table[0] << 16)) & 0xFFFFFFFFL); + } + + public int getCurrentNonce() { + return (int) table[(2 + index)]; + } + + void advanceToNextNonce() { + int nonce = getCurrentNonce(); + table[(2 + index)] = generateEntry(); + index = (nonce & 0x0F); + } + + @Override + public String toString() { + return "NonceState{" + + "table=" + Arrays.toString(table) + + ", index=" + index + + '}'; + } + } + + // TODO replace with java.util.function.Supplier when min API level >= 24 + @FunctionalInterface + private interface Supplier { + T get(); + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java index d5ac74c01d..f814a1082f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java @@ -1,16 +1,13 @@ package info.nightscout.androidaps.plugins.pump.omnipod.driver.comm; import android.content.Intent; -import android.text.TextUtils; -import org.apache.commons.lang3.StringUtils; import org.joda.time.DateTime; import org.joda.time.Duration; import java.util.ArrayList; import java.util.Date; import java.util.List; -import java.util.Objects; import dagger.android.HasAndroidInjector; import info.nightscout.androidaps.MainApp; @@ -22,7 +19,6 @@ import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.events.Event; -import info.nightscout.androidaps.events.EventRefreshOverview; import info.nightscout.androidaps.interfaces.ActivePluginProvider; import info.nightscout.androidaps.interfaces.TreatmentsInterface; import info.nightscout.androidaps.logging.AAPSLogger; @@ -32,7 +28,6 @@ import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotifi import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress; import info.nightscout.androidaps.plugins.general.overview.notifications.Notification; import info.nightscout.androidaps.plugins.pump.common.data.TempBasalPair; -import info.nightscout.androidaps.plugins.pump.common.defs.PumpStatusType; import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil; @@ -60,9 +55,6 @@ import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.PodReturne import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoRecentPulseLog; import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSet; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSlot; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertType; import info.nightscout.androidaps.plugins.pump.omnipod.defs.FaultEventCode; import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodCommunicationManagerInterface; import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType; @@ -74,8 +66,6 @@ import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManage import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus; import info.nightscout.androidaps.plugins.pump.omnipod.driver.db.PodHistory; import info.nightscout.androidaps.plugins.pump.omnipod.driver.db.PodHistoryEntryType; -import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodAcknowledgeAlertsChanged; -import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodPumpValuesChanged; import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil; import info.nightscout.androidaps.utils.resources.ResourceHelper; @@ -97,9 +87,6 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface private static AapsOmnipodManager instance; - private Date lastBolusTime; - private Double lastBolusUnits; - public static AapsOmnipodManager getInstance() { return instance; } @@ -126,12 +113,6 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface this.activePlugin = activePlugin; this.pumpStatus = _pumpStatus; - podStateManager.setStateChangedHandler(manager -> { - // Handle pod state changes - updatePumpStatus(manager); - omnipodUtil.notifyDeviceStatusChanged(); - }); - delegate = new OmnipodManager(aapsLogger, sp, communicationService, podStateManager); instance = this; } @@ -140,74 +121,6 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface return podStateManager; } - private void updatePumpStatus(PodStateManager podStateManager) { - if (pumpStatus != null) { - if (!podStateManager.hasState()) { - pumpStatus.ackAlertsText = null; - pumpStatus.ackAlertsAvailable = false; - pumpStatus.lastBolusTime = null; - pumpStatus.lastBolusAmount = null; - pumpStatus.reservoirRemainingUnits = 0.0; - pumpStatus.pumpStatusType = PumpStatusType.Suspended; - sendEvent(new EventOmnipodAcknowledgeAlertsChanged()); - sendEvent(new EventOmnipodPumpValuesChanged()); - sendEvent(new EventRefreshOverview("Omnipod Pump", false)); - } else { - // Update active alerts - if (podStateManager.hasActiveAlerts()) { - List alerts = translateActiveAlerts(podStateManager); - String alertsText = TextUtils.join("\n", alerts); - - if (!pumpStatus.ackAlertsAvailable || !alertsText.equals(pumpStatus.ackAlertsText)) { - pumpStatus.ackAlertsAvailable = true; - pumpStatus.ackAlertsText = TextUtils.join("\n", alerts); - - sendEvent(new EventOmnipodAcknowledgeAlertsChanged()); - } - } else { - if (pumpStatus.ackAlertsAvailable || StringUtils.isNotEmpty(pumpStatus.ackAlertsText)) { - pumpStatus.ackAlertsText = null; - pumpStatus.ackAlertsAvailable = false; - sendEvent(new EventOmnipodAcknowledgeAlertsChanged()); - } - } - - // Update other info: last bolus, units remaining, suspended - if (!Objects.equals(lastBolusTime, pumpStatus.lastBolusTime) // - || !Objects.equals(lastBolusUnits, pumpStatus.lastBolusAmount) // - || !isReservoirStatusUpToDate(pumpStatus, podStateManager.getReservoirLevel()) - || podStateManager.isSuspended() != PumpStatusType.Suspended.equals(pumpStatus.pumpStatusType)) { - pumpStatus.lastBolusTime = lastBolusTime; - pumpStatus.lastBolusAmount = lastBolusUnits; - pumpStatus.reservoirRemainingUnits = podStateManager.getReservoirLevel() == null ? 75.0 : podStateManager.getReservoirLevel(); - pumpStatus.pumpStatusType = podStateManager.isSuspended() ? PumpStatusType.Suspended : PumpStatusType.Running; - sendEvent(new EventOmnipodPumpValuesChanged()); - - if (podStateManager.isSuspended() != PumpStatusType.Suspended.equals(pumpStatus.pumpStatusType)) { - sendEvent(new EventRefreshOverview("Omnipod Pump", false)); - } - } - } - } - } - - private List translateActiveAlerts(PodStateManager podStateManager) { - List translatedAlerts = new ArrayList<>(); - AlertSet activeAlerts = podStateManager.getActiveAlerts(); - if (activeAlerts == null) { - return translatedAlerts; - } - for (AlertSlot alertSlot : activeAlerts.getAlertSlots()) { - translatedAlerts.add(translateAlertType(podStateManager.getConfiguredAlertType(alertSlot))); - } - return translatedAlerts; - } - - private static boolean isReservoirStatusUpToDate(OmnipodPumpStatus pumpStatus, Double unitsRemaining) { - double expectedUnitsRemaining = unitsRemaining == null ? 75.0 : unitsRemaining; - return Math.abs(expectedUnitsRemaining - pumpStatus.reservoirRemainingUnits) < 0.000001; - } - @Override public PumpEnactResult initPod(PodInitActionType podInitActionType, PodInitReceiver podInitReceiver, Profile profile) { long time = System.currentTimeMillis(); @@ -306,7 +219,6 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); } - return new PumpEnactResult(injector).success(true).enacted(true); } @@ -356,11 +268,6 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface double unitsDelivered = bolusDeliveryResult.getUnitsDelivered(); - if (pumpStatus != null && !detailedBolusInfo.isSMB) { - lastBolusTime = pumpStatus.lastBolusTime = bolusStarted; - lastBolusUnits = pumpStatus.lastBolusAmount = unitsDelivered; - } - long pumpId = addSuccessToHistory(bolusStarted.getTime(), PodHistoryEntryType.SetBolus, unitsDelivered + ";" + detailedBolusInfo.carbs); detailedBolusInfo.date = bolusStarted.getTime(); @@ -467,12 +374,6 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface return new PumpEnactResult(injector).success(true).enacted(true); } - @Override - public void setPumpStatus(OmnipodPumpStatus pumpStatus) { - this.pumpStatus = pumpStatus; - updatePumpStatus(podStateManager); - } - // TODO should we add this to the OmnipodCommunicationManager interface? public PumpEnactResult getPodInfo(PodInfoType podInfoType) { long time = System.currentTimeMillis(); @@ -554,10 +455,6 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface return delegate.isReadyForDelivery(); } - public String getPodStateAsString() { - return podStateManager.toString(); - } - private void reportImplicitlyCanceledTbr() { //TreatmentsPlugin plugin = TreatmentsPlugin.getPlugin(); TreatmentsInterface plugin = activePlugin.getActiveTreatments(); @@ -718,28 +615,6 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface sendEvent(new EventNewNotification(notification)); } - private String translateAlertType(AlertType alertType) { - if (alertType == null) { - return getStringResource(R.string.omnipod_alert_unknown_alert); - } - switch (alertType) { - case FINISH_PAIRING_REMINDER: - return getStringResource(R.string.omnipod_alert_finish_pairing_reminder); - case FINISH_SETUP_REMINDER: - return getStringResource(R.string.omnipod_alert_finish_setup_reminder_reminder); - case EXPIRATION_ALERT: - return getStringResource(R.string.omnipod_alert_expiration); - case EXPIRATION_ADVISORY_ALERT: - return getStringResource(R.string.omnipod_alert_expiration_advisory); - case SHUTDOWN_IMMINENT_ALARM: - return getStringResource(R.string.omnipod_alert_shutdown_imminent); - case LOW_RESERVOIR_ALERT: - return getStringResource(R.string.omnipod_alert_low_reservoir); - default: - return alertType.name(); - } - } - private boolean isBolusBeepsEnabled() { return this.pumpStatus.beepBolusEnabled; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java index 8d5feea0a5..1d365c6dba 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java @@ -1,631 +1,182 @@ package info.nightscout.androidaps.plugins.pump.omnipod.driver.comm; -import com.google.gson.Gson; +import android.text.TextUtils; import org.apache.commons.lang3.StringUtils; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.Duration; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Objects; -import javax.inject.Inject; - -import dagger.android.HasAndroidInjector; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.events.Event; +import info.nightscout.androidaps.events.EventRefreshOverview; import info.nightscout.androidaps.logging.AAPSLogger; -import info.nightscout.androidaps.logging.LTag; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoFaultEvent; +import info.nightscout.androidaps.plugins.bus.RxBusWrapper; +import info.nightscout.androidaps.plugins.pump.common.defs.PumpStatusType; import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSet; import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSlot; import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.DeliveryStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.FirmwareVersion; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.SetupProgress; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BasalSchedule; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateChangedHandler; import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmniCRC; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodAcknowledgeAlertsChanged; +import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodPumpValuesChanged; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil; -import info.nightscout.androidaps.utils.DateUtil; +import info.nightscout.androidaps.utils.resources.ResourceHelper; import info.nightscout.androidaps.utils.sharedPreferences.SP; -public class AapsPodStateManager implements PodStateManager { +public class AapsPodStateManager extends PodStateManager { - @Inject protected AAPSLogger aapsLogger; - @Inject protected SP sp; - @Inject protected OmnipodUtil omnipodUtil; + private final AAPSLogger aapsLogger; + private final SP sp; + private final OmnipodUtil omnipodUtil; + private final OmnipodPumpStatus omnipodPumpStatus; + private final RxBusWrapper rxBus; + private final ResourceHelper resourceHelper; - private PodState podState; - private PodStateChangedHandler stateChangedHandler; + public AapsPodStateManager(AAPSLogger aapsLogger, SP sp, OmnipodUtil omnipodUtil, + OmnipodPumpStatus omnipodPumpStatus, RxBusWrapper rxBus, + ResourceHelper resourceHelper) { + super(aapsLogger); - public AapsPodStateManager(HasAndroidInjector injector) { - injector.androidInjector().inject(this); + if (aapsLogger == null) { + throw new IllegalArgumentException("aapsLogger can not be null"); + } + if (sp == null) { + throw new IllegalArgumentException("sp can not be null"); + } + if (omnipodUtil == null) { + throw new IllegalArgumentException("omnipodUtil can not be null"); + } + if (omnipodPumpStatus == null) { + throw new IllegalArgumentException("omnipodPumpStatus can not be null"); + } + if (rxBus == null) { + throw new IllegalArgumentException("rxBus can not be null"); + } + if (resourceHelper == null) { + throw new IllegalArgumentException("resourceHelper can not be null"); + } - // TODO is there something like @PostConstruct in Dagger? if so, we should probably move loading the pod state there - loadPodState(); - } - - @Override public boolean hasState() { - return podState != null; - } - - @Override public void removeState() { - this.podState = null; - persistPodState(); - notifyPodStateChanged(); + this.aapsLogger = aapsLogger; + this.sp = sp; + this.omnipodUtil = omnipodUtil; + this.omnipodPumpStatus = omnipodPumpStatus; + this.rxBus = rxBus; + this.resourceHelper = resourceHelper; } @Override - public void initState(int address) { - if (hasState()) { - throw new IllegalStateException("Can not init a new pod state: podState <> null"); - } - podState = new PodState(address); - persistPodState(); - notifyPodStateChanged(); - } - - @Override public boolean isPaired() { - return hasState() // - && podState.getLot() != null && podState.getTid() != null // - && podState.getPiVersion() != null && podState.getPmVersion() != null // - && podState.getTimeZone() != null // - && podState.getSetupProgress() != null; + protected String readPodState() { + return sp.getString(OmnipodConst.Prefs.PodState, ""); } @Override - public void setPairingParameters(int lot, int tid, FirmwareVersion piVersion, FirmwareVersion pmVersion, DateTimeZone timeZone) { - if (!hasState()) { - throw new IllegalStateException("Cannot set pairing parameters: podState is null"); - } - if (isPaired()) { - throw new IllegalStateException("Cannot set pairing parameters: pairing parameters have already been set"); - } - if (piVersion == null) { - throw new IllegalArgumentException("Cannot set pairing parameters: piVersion can not be null"); - } - if (pmVersion == null) { - throw new IllegalArgumentException("Cannot set pairing parameters: pmVersion can not be null"); - } - if (timeZone == null) { - throw new IllegalArgumentException("Cannot set pairing parameters: timeZone can not be null"); - } - - setAndStore(() -> { - podState.setLot(lot); - podState.setTid(tid); - podState.setPiVersion(piVersion); - podState.setPmVersion(pmVersion); - podState.setTimeZone(timeZone); - podState.setNonceState(new NonceState(lot, tid)); - podState.setSetupProgress(SetupProgress.ADDRESS_ASSIGNED); - podState.getConfiguredAlerts().put(AlertSlot.SLOT7, AlertType.FINISH_SETUP_REMINDER); - }); - } - - @Override public int getAddress() { - return getSafe(() -> podState.getAddress()); - } - - @Override public int getMessageNumber() { - return getSafe(() -> podState.getMessageNumber()); - } - - @Override public void setMessageNumber(int messageNumber) { - setAndStore(() -> podState.setMessageNumber(messageNumber)); - } - - @Override public int getPacketNumber() { - return getSafe(() -> podState.getPacketNumber()); - } - - @Override public void setPacketNumber(int packetNumber) { - setAndStore(() -> podState.setPacketNumber(packetNumber)); - } - - @Override public void increaseMessageNumber() { - setAndStore(() -> podState.setMessageNumber((podState.getMessageNumber() + 1) & 0b1111)); - } - - @Override public void increasePacketNumber() { - setAndStore(() -> podState.setPacketNumber((podState.getPacketNumber() + 1) & 0b11111)); - } - - @Override public synchronized void resyncNonce(int syncWord, int sentNonce, int sequenceNumber) { - if (!isPaired()) { - throw new IllegalStateException("Cannot resync nonce: Pod is not paired yet"); - } - - int sum = (sentNonce & 0xFFFF) - + OmniCRC.crc16lookup[sequenceNumber] - + (podState.getLot() & 0xFFFF) - + (podState.getTid() & 0xFFFF); - int seed = ((sum & 0xFFFF) ^ syncWord); - NonceState nonceState = new NonceState(podState.getLot(), podState.getTid(), (byte) (seed & 0xFF)); - - setAndStore(() -> podState.setNonceState(nonceState)); - } - - @Override public synchronized int getCurrentNonce() { - if (!isPaired()) { - throw new IllegalStateException("Cannot get current nonce: Pod is not paired yet"); - } - return podState.getNonceState().getCurrentNonce(); - } - - @Override public synchronized void advanceToNextNonce() { - if (!isPaired()) { - throw new IllegalStateException("Cannot advance to next nonce: Pod is not paired yet"); - } - setAndStore(() -> podState.getNonceState().advanceToNextNonce()); - } - - @Override public boolean hasFaultEvent() { - return getSafe(() -> podState.getFaultEvent()) != null; - } - - @Override public PodInfoFaultEvent getFaultEvent() { - return getSafe(() -> podState.getFaultEvent()); - } - - @Override public void setFaultEvent(PodInfoFaultEvent faultEvent) { - setAndStore(() -> podState.setFaultEvent(faultEvent)); - } - - @Override public AlertType getConfiguredAlertType(AlertSlot alertSlot) { - return getSafe(() -> podState.getConfiguredAlerts().get(alertSlot)); - } - - @Override public void putConfiguredAlert(AlertSlot alertSlot, AlertType alertType) { - setAndStore(() -> podState.getConfiguredAlerts().put(alertSlot, alertType)); - } - - @Override public void removeConfiguredAlert(AlertSlot alertSlot) { - setAndStore(() -> podState.getConfiguredAlerts().remove(alertSlot)); - } - - @Override public boolean hasActiveAlerts() { - AlertSet activeAlerts = podState.getActiveAlerts(); - return activeAlerts != null && activeAlerts.size() > 0; - } - - @Override public AlertSet getActiveAlerts() { - return getSafe(() -> podState.getActiveAlerts()); - } - - @Override public Integer getLot() { - return getSafe(() -> podState.getLot()); - } - - @Override public Integer getTid() { - return getSafe(() -> podState.getTid()); - } - - @Override public FirmwareVersion getPiVersion() { - return getSafe(() -> podState.getPiVersion()); - } - - @Override public FirmwareVersion getPmVersion() { - return getSafe(() -> podState.getPmVersion()); - } - - @Override public DateTimeZone getTimeZone() { - return getSafe(() -> podState.getTimeZone()); - } - - @Override public void setTimeZone(DateTimeZone timeZone) { - if (timeZone == null) { - throw new IllegalArgumentException("Time zone can not be null"); - } - setAndStore(() -> podState.setTimeZone(timeZone)); - } - - @Override public DateTime getTime() { - DateTime now = DateTime.now(); - return now.withZone(getSafe(() -> podState.getTimeZone())); - } - - public DateTime getActivatedAt() { - DateTime activatedAt = getSafe(() -> podState.getActivatedAt()); - return activatedAt == null ? null : activatedAt.withZone(getSafe(() -> podState.getTimeZone())); - } - - public DateTime getExpiresAt() { - DateTime expiresAt = getSafe(() -> podState.getExpiresAt()); - return expiresAt == null ? null : expiresAt.withZone(getSafe(() -> podState.getTimeZone())); - } - - // TODO doesn't belong here - public String getExpiryDateAsString() { - DateTime expiresAt = getExpiresAt(); - return expiresAt == null ? "???" : DateUtil.dateAndTimeString(expiresAt.toDate()); - } - - public SetupProgress getSetupProgress() { - return getSafe(() -> podState.getSetupProgress()); - } - - public void setSetupProgress(SetupProgress setupProgress) { - if (setupProgress == null) { - throw new IllegalArgumentException("Setup progress can not be null"); - } - setAndStore(() -> podState.setSetupProgress(setupProgress)); - } - - @Override public boolean isSuspended() { - return getSafe(() -> podState.isSuspended()); - } - - @Override public Double getReservoirLevel() { - return getSafe(() -> podState.getReservoirLevel()); - } - - @Override public Duration getScheduleOffset() { - DateTime now = getTime(); - DateTime startOfDay = new DateTime(now.getYear(), now.getMonthOfYear(), now.getDayOfMonth(), - 0, 0, 0, getSafe(() -> podState.getTimeZone())); - return new Duration(startOfDay, now); - } - - @Override public BasalSchedule getBasalSchedule() { - return getSafe(() -> podState.getBasalSchedule()); - } - - @Override public void setBasalSchedule(BasalSchedule basalSchedule) { - setAndStore(() -> podState.setBasalSchedule(basalSchedule)); - } - - @Override public DeliveryStatus getLastDeliveryStatus() { - return getSafe(() -> podState.getLastDeliveryStatus()); - } - - @Override public void updateFromStatusResponse(StatusResponse statusResponse) { - if (!hasState()) { - throw new IllegalStateException("Cannot update from status response: podState is null"); - } - setAndStore(() -> { - if (podState.getActivatedAt() == null) { - DateTime activatedAtCalculated = getTime().minus(statusResponse.getTimeActive()); - podState.setActivatedAt(activatedAtCalculated); - } - DateTime expiresAt = podState.getExpiresAt(); - DateTime expiresAtCalculated = podState.getActivatedAt().plus(OmnipodConst.NOMINAL_POD_LIFE); - if (expiresAt == null || expiresAtCalculated.isBefore(expiresAt) || expiresAtCalculated.isAfter(expiresAt.plusMinutes(1))) { - podState.setExpiresAt(expiresAtCalculated); - } - - boolean newSuspendedState = statusResponse.getDeliveryStatus() == DeliveryStatus.SUSPENDED; - if (podState.isSuspended() != newSuspendedState) { - aapsLogger.info(LTag.PUMPCOMM, "Updating pod suspended state in updateFromStatusResponse. newSuspendedState={}, statusResponse={}", newSuspendedState, statusResponse.toString()); - podState.setSuspended(newSuspendedState); - } - podState.setActiveAlerts(statusResponse.getAlerts()); - podState.setLastDeliveryStatus(statusResponse.getDeliveryStatus()); - podState.setReservoirLevel(statusResponse.getReservoirLevel()); - }); + protected void storePodState(String podState) { + sp.putString(OmnipodConst.Prefs.PodState, podState); } @Override - public void setStateChangedHandler(PodStateChangedHandler handler) { - // FIXME this is an ugly workaround for not being able to serialize the PodStateChangedHandler - if (stateChangedHandler != null) { - throw new IllegalStateException("A PodStateChangedHandler has already been already registered"); - } - stateChangedHandler = handler; - } + protected void notifyPodStateChanged() { + if (omnipodPumpStatus != null) { + if (!hasState()) { + omnipodPumpStatus.ackAlertsText = null; + omnipodPumpStatus.ackAlertsAvailable = false; + omnipodPumpStatus.lastBolusTime = null; + omnipodPumpStatus.lastBolusAmount = null; + omnipodPumpStatus.reservoirRemainingUnits = 0.0; + omnipodPumpStatus.pumpStatusType = PumpStatusType.Suspended; + sendEvent(new EventOmnipodAcknowledgeAlertsChanged()); + sendEvent(new EventOmnipodPumpValuesChanged()); + sendEvent(new EventRefreshOverview("Omnipod Pump", false)); + } else { + // Update active alerts + if (hasActiveAlerts()) { + List alerts = getTranslatedActiveAlerts(); + String alertsText = TextUtils.join("\n", alerts); - private void setAndStore(Runnable runnable) { - if (!hasState()) { - throw new IllegalStateException("Cannot mutate PodState: podState is null"); - } - runnable.run(); - persistPodState(); - notifyPodStateChanged(); - } + if (!omnipodPumpStatus.ackAlertsAvailable || !alertsText.equals(omnipodPumpStatus.ackAlertsText)) { + omnipodPumpStatus.ackAlertsAvailable = true; + omnipodPumpStatus.ackAlertsText = TextUtils.join("\n", alerts); - private void persistPodState() { - Gson gson = omnipodUtil.getGsonInstance(); - String gsonValue = gson.toJson(podState); - aapsLogger.info(LTag.PUMPCOMM, "PodState-SP: Saved PodState to SharedPreferences: " + gsonValue); - sp.putString(OmnipodConst.Prefs.PodState, gsonValue); - } + sendEvent(new EventOmnipodAcknowledgeAlertsChanged()); + } + } else { + if (omnipodPumpStatus.ackAlertsAvailable || StringUtils.isNotEmpty(omnipodPumpStatus.ackAlertsText)) { + omnipodPumpStatus.ackAlertsText = null; + omnipodPumpStatus.ackAlertsAvailable = false; + sendEvent(new EventOmnipodAcknowledgeAlertsChanged()); + } + } - private void notifyPodStateChanged() { - if (stateChangedHandler != null) { - stateChangedHandler.handle(this); - } - } + Date lastBolusStartTime = getLastBolusStartTime() == null ? null : getLastBolusStartTime().toDate(); + Double lastBolusAmount = getLastBolusAmount(); - // Not actually "safe" as it throws an Exception, but it prevents NPEs - private T getSafe(Supplier supplier) { - if (!hasState()) { - throw new IllegalStateException("Cannot read from PodState: podState is null"); - } - return supplier.get(); - } + // Update other info: last bolus, units remaining, suspended + if (Objects.equals(lastBolusStartTime, omnipodPumpStatus.lastBolusTime) // + || !Objects.equals(lastBolusAmount, omnipodPumpStatus.lastBolusAmount) // + || !isReservoirStatusUpToDate(omnipodPumpStatus, getReservoirLevel()) + || isSuspended() != PumpStatusType.Suspended.equals(omnipodPumpStatus.pumpStatusType)) { + omnipodPumpStatus.lastBolusTime = lastBolusStartTime; + omnipodPumpStatus.lastBolusAmount = lastBolusAmount; + omnipodPumpStatus.reservoirRemainingUnits = getReservoirLevel() == null ? 75.0 : getReservoirLevel(); + omnipodPumpStatus.pumpStatusType = isSuspended() ? PumpStatusType.Suspended : PumpStatusType.Running; + sendEvent(new EventOmnipodPumpValuesChanged()); - private void loadPodState() { - podState = null; - - String storedPodState = sp.getString(OmnipodConst.Prefs.PodState, ""); - - if (StringUtils.isEmpty(storedPodState)) { - aapsLogger.info(LTag.PUMP, "PodState-SP: no PodState present in SharedPreferences"); - } else { - aapsLogger.info(LTag.PUMP, "PodState-SP: loaded PodState from SharedPreferences: " + storedPodState); - try { - podState = omnipodUtil.getGsonInstance().fromJson(storedPodState, PodState.class); - } catch (Exception ex) { - aapsLogger.error(LTag.PUMPCOMM, "PodState-SP: could not deserialize PodState", ex); + if (isSuspended() != PumpStatusType.Suspended.equals(omnipodPumpStatus.pumpStatusType)) { + sendEvent(new EventRefreshOverview("Omnipod Pump", false)); + } + } } } - - notifyPodStateChanged(); + omnipodUtil.notifyDeviceStatusChanged(); } - @Override public String toString() { - return "AapsPodStateManager{" + - "podState=" + podState + - '}'; + private List getTranslatedActiveAlerts() { + List translatedAlerts = new ArrayList<>(); + AlertSet activeAlerts = getActiveAlerts(); + + for (AlertSlot alertSlot : activeAlerts.getAlertSlots()) { + translatedAlerts.add(translateAlertType(getConfiguredAlertType(alertSlot))); + } + return translatedAlerts; } - private static class PodState { - private final int address; - private Integer lot; - private Integer tid; - private FirmwareVersion piVersion; - private FirmwareVersion pmVersion; - private int packetNumber; - private int messageNumber; - private DateTimeZone timeZone; - private DateTime activatedAt; - private DateTime expiresAt; - private PodInfoFaultEvent faultEvent; - private Double reservoirLevel; - private boolean suspended; - private NonceState nonceState; - private SetupProgress setupProgress; - private DeliveryStatus lastDeliveryStatus; - private AlertSet activeAlerts; - private BasalSchedule basalSchedule; - private final Map configuredAlerts = new HashMap<>(); - private PodState(int address) { - this.address = address; + private String translateAlertType(AlertType alertType) { + if (alertType == null) { + return getStringResource(R.string.omnipod_alert_unknown_alert); } - - public int getAddress() { - return address; - } - - public Integer getLot() { - return lot; - } - - public void setLot(int lot) { - this.lot = lot; - } - - public Integer getTid() { - return tid; - } - - public void setTid(int tid) { - this.tid = tid; - } - - public FirmwareVersion getPiVersion() { - return piVersion; - } - - public void setPiVersion(FirmwareVersion piVersion) { - if (this.piVersion != null) { - throw new IllegalStateException("piVersion has already been set"); - } - if (piVersion == null) { - throw new IllegalArgumentException("piVersion can not be null"); - } - this.piVersion = piVersion; - } - - public FirmwareVersion getPmVersion() { - return pmVersion; - } - - public void setPmVersion(FirmwareVersion pmVersion) { - this.pmVersion = pmVersion; - } - - public int getPacketNumber() { - return packetNumber; - } - - public void setPacketNumber(int packetNumber) { - this.packetNumber = packetNumber; - } - - public int getMessageNumber() { - return messageNumber; - } - - public void setMessageNumber(int messageNumber) { - this.messageNumber = messageNumber; - } - - public DateTimeZone getTimeZone() { - return timeZone; - } - - public void setTimeZone(DateTimeZone timeZone) { - this.timeZone = timeZone; - } - - public DateTime getActivatedAt() { - return activatedAt; - } - - public void setActivatedAt(DateTime activatedAt) { - this.activatedAt = activatedAt; - } - - public DateTime getExpiresAt() { - return expiresAt; - } - - public void setExpiresAt(DateTime expiresAt) { - this.expiresAt = expiresAt; - } - - public PodInfoFaultEvent getFaultEvent() { - return faultEvent; - } - - public void setFaultEvent(PodInfoFaultEvent faultEvent) { - this.faultEvent = faultEvent; - } - - public Double getReservoirLevel() { - return reservoirLevel; - } - - public void setReservoirLevel(Double reservoirLevel) { - this.reservoirLevel = reservoirLevel; - } - - public boolean isSuspended() { - return suspended; - } - - public void setSuspended(boolean suspended) { - this.suspended = suspended; - } - - public NonceState getNonceState() { - return nonceState; - } - - public void setNonceState(NonceState nonceState) { - this.nonceState = nonceState; - } - - public SetupProgress getSetupProgress() { - return setupProgress; - } - - public void setSetupProgress(SetupProgress setupProgress) { - this.setupProgress = setupProgress; - } - - public DeliveryStatus getLastDeliveryStatus() { - return lastDeliveryStatus; - } - - public void setLastDeliveryStatus(DeliveryStatus lastDeliveryStatus) { - this.lastDeliveryStatus = lastDeliveryStatus; - } - - public AlertSet getActiveAlerts() { - return activeAlerts; - } - - public void setActiveAlerts(AlertSet activeAlerts) { - this.activeAlerts = activeAlerts; - } - - public BasalSchedule getBasalSchedule() { - return basalSchedule; - } - - public void setBasalSchedule(BasalSchedule basalSchedule) { - this.basalSchedule = basalSchedule; - } - - public Map getConfiguredAlerts() { - return configuredAlerts; - } - - @Override public String toString() { - return "PodState{" + - "address=" + address + - ", lot=" + lot + - ", tid=" + tid + - ", piVersion=" + piVersion + - ", pmVersion=" + pmVersion + - ", packetNumber=" + packetNumber + - ", messageNumber=" + messageNumber + - ", timeZone=" + timeZone + - ", activatedAt=" + activatedAt + - ", expiresAt=" + expiresAt + - ", faultEvent=" + faultEvent + - ", reservoirLevel=" + reservoirLevel + - ", suspended=" + suspended + - ", nonceState=" + nonceState + - ", setupProgress=" + setupProgress + - ", lastDeliveryStatus=" + lastDeliveryStatus + - ", activeAlerts=" + activeAlerts + - ", basalSchedule=" + basalSchedule + - ", configuredAlerts=" + configuredAlerts + - '}'; + switch (alertType) { + case FINISH_PAIRING_REMINDER: + return getStringResource(R.string.omnipod_alert_finish_pairing_reminder); + case FINISH_SETUP_REMINDER: + return getStringResource(R.string.omnipod_alert_finish_setup_reminder_reminder); + case EXPIRATION_ALERT: + return getStringResource(R.string.omnipod_alert_expiration); + case EXPIRATION_ADVISORY_ALERT: + return getStringResource(R.string.omnipod_alert_expiration_advisory); + case SHUTDOWN_IMMINENT_ALARM: + return getStringResource(R.string.omnipod_alert_shutdown_imminent); + case LOW_RESERVOIR_ALERT: + return getStringResource(R.string.omnipod_alert_low_reservoir); + default: + return alertType.name(); } } - private static class NonceState { - private final long[] table = new long[21]; - private int index; - - private NonceState(int lot, int tid) { - initializeTable(lot, tid, (byte) 0x00); - } - - private NonceState(int lot, int tid, byte seed) { - initializeTable(lot, tid, seed); - } - - private void initializeTable(int lot, int tid, byte seed) { - table[0] = (long) (lot & 0xFFFF) + 0x55543DC3L + (((long) (lot) & 0xFFFFFFFFL) >> 16); - table[0] = table[0] & 0xFFFFFFFFL; - table[1] = (tid & 0xFFFF) + 0xAAAAE44EL + (((long) (tid) & 0xFFFFFFFFL) >> 16); - table[1] = table[1] & 0xFFFFFFFFL; - index = 0; - table[0] += seed; - for (int i = 0; i < 16; i++) { - table[2 + i] = generateEntry(); - } - index = (int) ((table[0] + table[1]) & 0X0F); - } - - private int generateEntry() { - table[0] = (((table[0] >> 16) + (table[0] & 0xFFFF) * 0x5D7FL) & 0xFFFFFFFFL); - table[1] = (((table[1] >> 16) + (table[1] & 0xFFFF) * 0x8CA0L) & 0xFFFFFFFFL); - return (int) ((table[1] + (table[0] << 16)) & 0xFFFFFFFFL); - } - - public int getCurrentNonce() { - return (int) table[(2 + index)]; - } - - public void advanceToNextNonce() { - int nonce = getCurrentNonce(); - table[(2 + index)] = generateEntry(); - index = (nonce & 0x0F); - } - - @Override - public String toString() { - return "NonceState{" + - "table=" + Arrays.toString(table) + - ", index=" + index + - '}'; - } + private String getStringResource(int id, Object... args) { + return resourceHelper.gs(id, args); } - // TODO replace with java.util.function.Supplier when min API level >= 24 - @FunctionalInterface - private interface Supplier { - T get(); + private static boolean isReservoirStatusUpToDate(OmnipodPumpStatus pumpStatus, Double unitsRemaining) { + double expectedUnitsRemaining = unitsRemaining == null ? 75.0 : unitsRemaining; + return Math.abs(expectedUnitsRemaining - pumpStatus.reservoirRemainingUnits) < 0.000001; + } + + private void sendEvent(Event event) { + rxBus.send(event); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java index 8100f2afff..bc8440adfc 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java @@ -109,7 +109,7 @@ public class RileyLinkOmnipodService extends RileyLinkService { private void initializeErosOmnipodManager() { AapsOmnipodManager instance = AapsOmnipodManager.getInstance(); if (instance == null) { - PodStateManager podStateManager = new AapsPodStateManager(injector); + PodStateManager podStateManager = new AapsPodStateManager(aapsLogger, sp, omnipodUtil, omnipodPumpStatus, rxBus, resourceHelper); omnipodUtil.setPodStateManager(podStateManager); OmnipodCommunicationManager omnipodCommunicationService = new OmnipodCommunicationManager(injector, rfspy); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodConst.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodConst.java index f7b78250c3..35889383c2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodConst.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodConst.java @@ -44,6 +44,7 @@ public class OmnipodConst { public static final int DEFAULT_ADDRESS = 0xffffffff; public static final Duration AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION = Duration.millis(1500); + public static final Duration AVERAGE_TEMP_BASAL_COMMAND_COMMUNICATION_DURATION = Duration.millis(1500); public static final Duration SERVICE_DURATION = Duration.standardHours(80); public static final Duration EXPIRATION_ADVISORY_WINDOW = Duration.standardHours(9); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod_dash/comm/OmnipodDashCommunicationManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod_dash/comm/OmnipodDashCommunicationManager.java index 992a248994..db594e6af1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod_dash/comm/OmnipodDashCommunicationManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod_dash/comm/OmnipodDashCommunicationManager.java @@ -114,11 +114,6 @@ public class OmnipodDashCommunicationManager implements OmnipodCommunicationMana return null; } - @Override - public void setPumpStatus(OmnipodPumpStatus pumpStatusLocal) { - - } - @Override public PodInfoRecentPulseLog readPulseLog() { return null; diff --git a/app/src/main/res/layout/omnipod_fragment.xml b/app/src/main/res/layout/omnipod_fragment.xml index 2068f90557..c1ac656f2d 100644 --- a/app/src/main/res/layout/omnipod_fragment.xml +++ b/app/src/main/res/layout/omnipod_fragment.xml @@ -26,8 +26,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" - android:paddingBottom="5dp" android:paddingTop="2dp" + android:paddingBottom="5dp" android:visibility="gone"> @@ -93,10 +93,10 @@ @@ -119,8 +119,8 @@ android:layout_height="wrap_content" android:layout_weight="0" android:gravity="center_horizontal" - android:paddingEnd="2dp" android:paddingStart="2dp" + android:paddingEnd="2dp" android:text=":" android:textSize="14sp" /> @@ -133,12 +133,118 @@ android:paddingLeft="5dp" android:textColor="@android:color/white" android:textSize="14sp" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -175,7 +281,7 @@ - + @@ -212,7 +318,6 @@ android:textColor="@android:color/white" android:textSize="14sp" /> - @@ -270,10 +375,10 @@ @@ -316,10 +421,10 @@ @@ -361,10 +466,10 @@ @@ -406,10 +511,10 @@ @@ -432,8 +537,8 @@ android:layout_height="wrap_content" android:layout_weight="0" android:gravity="center_horizontal" - android:paddingEnd="2dp" android:paddingStart="2dp" + android:paddingEnd="2dp" android:text=":" android:textSize="14sp" /> @@ -453,10 +558,10 @@ @@ -498,10 +603,10 @@ @@ -543,10 +648,10 @@ @@ -621,8 +726,7 @@ android:drawableTop="@drawable/icon_cp_bolus_correction" android:paddingLeft="0dp" android:paddingRight="0dp" - android:text="@string/omnipod_read_pulse_log_short" - /> + android:text="@string/omnipod_read_pulse_log_short" /> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9f0a23abb0..4c754140dc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1982,5 +1982,8 @@ Unable to verify whether the bolus succeeded. Please verify that your Pod is bolusing or cancel the bolus. RL Stats Pulse Log + LOT + TID + PM / PI version From 62bda451a00381a1786734d7090260aad8128d12 Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Sun, 9 Aug 2020 13:36:08 +0200 Subject: [PATCH 11/17] Prevent NPE --- .../androidaps/plugins/pump/omnipod/OmnipodFragment.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt index 12e591cb23..5aef4f7449 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt @@ -23,7 +23,6 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyL import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodStatusRequest import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodDeviceState -import info.nightscout.androidaps.plugins.pump.omnipod.defs.SetupProgress import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.PodManagementActivity import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodDriverState import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus @@ -255,7 +254,7 @@ class OmnipodFragment : DaggerFragment() { omnipod_pod_status.text = resourceHelper.gs(R.string.omnipod_pod_not_initalized) omnipodPumpStatus.podAvailable = false omnipodPumpStatus.podNumber == null - } else if (driverState == OmnipodDriverState.Initalized_NoPod) { + } else if (driverState == OmnipodDriverState.Initalized_NoPod || !omnipodPumpStatus.podStateManager.hasState()) { omnipod_pod_address.text = resourceHelper.gs(R.string.omnipod_pod_name_no_info) omnipod_pod_lot.text = "-" omnipod_pod_tid.text = "-" From 050816ddf9ef0714a451b33e185de4b0ad0613bb Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Sun, 9 Aug 2020 14:04:24 +0200 Subject: [PATCH 12/17] Restore accidentally removed code --- .../plugins/pump/omnipod/OmnipodFragment.kt | 2 +- .../pump/omnipod/OmnipodPumpPlugin.java | 23 ++++++++++--------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt index 5aef4f7449..2c82dab36d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt @@ -254,7 +254,7 @@ class OmnipodFragment : DaggerFragment() { omnipod_pod_status.text = resourceHelper.gs(R.string.omnipod_pod_not_initalized) omnipodPumpStatus.podAvailable = false omnipodPumpStatus.podNumber == null - } else if (driverState == OmnipodDriverState.Initalized_NoPod || !omnipodPumpStatus.podStateManager.hasState()) { + } else if (driverState == OmnipodDriverState.Initalized_NoPod) { omnipod_pod_address.text = resourceHelper.gs(R.string.omnipod_pod_name_no_info) omnipod_pod_lot.text = "-" omnipod_pod_tid.text = "-" diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java index 2d6bd2306a..1b8db8f50f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java @@ -622,20 +622,21 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump setRefreshButtonEnabled(false); - try { - PodStateManager podStateManager = omnipodUtil.getPodStateManager(); - } catch(Exception ex) { + PodStateManager podStateManager = omnipodUtil.getPodStateManager(); + if (podStateManager.isPaired()) { + aapsLogger.debug(LTag.PUMP, "PodStateManager (saved): " + podStateManager); + + if (!isRefresh) { + pumpState = PumpDriverState.Initialized; + } + + // TODO handle if session state too old + getPodPumpStatus(); + } else { + aapsLogger.debug(LTag.PUMP, "No Pod running"); omnipodUtil.setDriverState(OmnipodDriverState.Initalized_NoPod); - throw ex; } - if (!isRefresh) { - pumpState = PumpDriverState.Initialized; - } - - // TODO handle if pod state too old - getPodPumpStatus(); - finishAction("Omnipod Pump"); // if (!sentIdToFirebase) { From da2c2110da2731fc6115b450399fda25d3ec4da7 Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Sun, 9 Aug 2020 14:06:45 +0200 Subject: [PATCH 13/17] Load pod state after initializing PodStateManager --- .../plugins/pump/omnipod/service/RileyLinkOmnipodService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java index bc8440adfc..b2e4d0fc34 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java @@ -110,6 +110,7 @@ public class RileyLinkOmnipodService extends RileyLinkService { AapsOmnipodManager instance = AapsOmnipodManager.getInstance(); if (instance == null) { PodStateManager podStateManager = new AapsPodStateManager(aapsLogger, sp, omnipodUtil, omnipodPumpStatus, rxBus, resourceHelper); + podStateManager.loadPodState(); omnipodUtil.setPodStateManager(podStateManager); OmnipodCommunicationManager omnipodCommunicationService = new OmnipodCommunicationManager(injector, rfspy); From 1787afda98185fc2833a7c63b7d602f46558243e Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Sun, 9 Aug 2020 16:41:16 +0200 Subject: [PATCH 14/17] Daggerize AapsPodStateManager --- .../dependencyInjection/OmnipodModule.kt | 20 +++- .../plugins/pump/omnipod/OmnipodFragment.kt | 34 +++--- .../pump/omnipod/OmnipodPumpPlugin.java | 13 ++- .../omnipod/defs/state/PodStateManager.java | 2 + .../omnipod/dialogs/PodManagementActivity.kt | 11 +- .../wizard/pages/InitPodRefreshAction.java | 4 +- .../dialogs/wizard/pages/PodInfoFragment.java | 6 +- .../omnipod/driver/OmnipodPumpStatus.java | 3 - .../driver/comm/AapsPodStateManager.java | 102 +++++++++--------- .../service/RileyLinkOmnipodService.java | 15 +-- .../pump/omnipod/util/OmnipodUtil.java | 35 +----- 11 files changed, 113 insertions(+), 132 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/OmnipodModule.kt b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/OmnipodModule.kt index dc8f3ddc77..a47a316fd2 100644 --- a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/OmnipodModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/OmnipodModule.kt @@ -1,7 +1,11 @@ package info.nightscout.androidaps.dependencyInjection import dagger.Module +import dagger.Provides import dagger.android.ContributesAndroidInjector +import info.nightscout.androidaps.logging.AAPSLogger +import info.nightscout.androidaps.plugins.bus.RxBusWrapper +import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodPumpPlugin import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.PodHistoryActivity @@ -11,8 +15,13 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.initpod.In import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.pages.InitPodRefreshAction import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.pages.PodInfoFragment import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.removepod.RemoveActionFragment +import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus +import info.nightscout.androidaps.plugins.pump.omnipod.driver.comm.AapsOmnipodManager import info.nightscout.androidaps.plugins.pump.omnipod.driver.comm.AapsPodStateManager import info.nightscout.androidaps.plugins.pump.omnipod.driver.ui.OmnipodUITask +import info.nightscout.androidaps.utils.resources.ResourceHelper +import info.nightscout.androidaps.utils.sharedPreferences.SP +import javax.inject.Singleton @Module @Suppress("unused") @@ -31,13 +40,20 @@ abstract class OmnipodModule { // Service @ContributesAndroidInjector abstract fun omnipodCommunicationManagerProvider(): OmnipodCommunicationManager + @ContributesAndroidInjector abstract fun aapsOmnipodManagerProvider(): AapsOmnipodManager // Data @ContributesAndroidInjector abstract fun omnipodUITaskProvider(): OmnipodUITask @ContributesAndroidInjector abstract fun initPodRefreshAction(): InitPodRefreshAction @ContributesAndroidInjector abstract fun podStateManager(): PodStateManager @ContributesAndroidInjector abstract fun initPodTask(): InitPodTask + @ContributesAndroidInjector abstract fun omnipodPumpPlugin(): OmnipodPumpPlugin - @ContributesAndroidInjector abstract fun initAapsPodStateManager(): AapsPodStateManager - + companion object { + @Provides + @Singleton + fun podStateManagerProvider(aapsLogger: AAPSLogger, sp: SP, omnipodPumpStatus: OmnipodPumpStatus, + rxBus: RxBusWrapper, resourceHelper: ResourceHelper): PodStateManager = + AapsPodStateManager(aapsLogger, sp, omnipodPumpStatus, rxBus, resourceHelper) + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt index 2c82dab36d..ff44fd1d4d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt @@ -23,6 +23,7 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyL import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodStatusRequest import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodDeviceState +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.PodManagementActivity import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodDriverState import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus @@ -60,6 +61,7 @@ class OmnipodFragment : DaggerFragment() { @Inject lateinit var omnipodPumpPlugin: OmnipodPumpPlugin @Inject lateinit var warnColors: WarnColors @Inject lateinit var omnipodPumpStatus: OmnipodPumpStatus + @Inject lateinit var podStateManager: PodStateManager @Inject lateinit var sp: SP @Inject lateinit var omnipodUtil: OmnipodUtil @Inject lateinit var rileyLinkServiceData: RileyLinkServiceData @@ -264,27 +266,27 @@ class OmnipodFragment : DaggerFragment() { omnipodPumpStatus.podAvailable = false omnipodPumpStatus.podNumber == null } else if (driverState == OmnipodDriverState.Initalized_PodInitializing) { - omnipod_pod_address.text = omnipodPumpStatus.podStateManager.address.toString() + omnipod_pod_address.text = podStateManager.address.toString() omnipod_pod_lot.text = "-" omnipod_pod_tid.text = "-" omnipod_pod_fw_version.text = "-" omnipod_pod_expiry.text = "-" - omnipod_pod_status.text = resourceHelper.gs(R.string.omnipod_pod_status_initalizing) + " (" + omnipodPumpStatus.podStateManager.getSetupProgress().name + ")" + omnipod_pod_status.text = resourceHelper.gs(R.string.omnipod_pod_status_initalizing) + " (" + podStateManager.getSetupProgress().name + ")" omnipodPumpStatus.podAvailable = false - omnipodPumpStatus.podNumber == omnipodPumpStatus.podStateManager.address.toString() + omnipodPumpStatus.podNumber == podStateManager.address.toString() } else { - omnipodPumpStatus.podLotNumber = "" + omnipodPumpStatus.podStateManager.lot + omnipodPumpStatus.podLotNumber = "" + podStateManager.lot omnipodPumpStatus.podAvailable = true - omnipod_pod_address.text = omnipodPumpStatus.podStateManager.address.toString() - omnipod_pod_lot.text = if (omnipodPumpStatus.podStateManager.lot == null) "" else omnipodPumpStatus.podStateManager.lot.toString() - omnipod_pod_tid.text = if (omnipodPumpStatus.podStateManager.tid == null) "" else omnipodPumpStatus.podStateManager.tid.toString() - if (omnipodPumpStatus.podStateManager.pmVersion == null || omnipodPumpStatus.podStateManager.piVersion == null) { + omnipod_pod_address.text = podStateManager.address.toString() + omnipod_pod_lot.text = if (podStateManager.lot == null) "" else podStateManager.lot.toString() + omnipod_pod_tid.text = if (podStateManager.tid == null) "" else podStateManager.tid.toString() + if (podStateManager.pmVersion == null || podStateManager.piVersion == null) { omnipod_pod_fw_version.text = "" } else { - omnipod_pod_fw_version.text = omnipodPumpStatus.podStateManager.pmVersion.toString() + " / " + omnipodPumpStatus.podStateManager.piVersion.toString() + omnipod_pod_fw_version.text = podStateManager.pmVersion.toString() + " / " + podStateManager.piVersion.toString() } - omnipod_pod_expiry.text = omnipodPumpStatus.podStateManager.expiryDateAsString - omnipodPumpStatus.podNumber = omnipodPumpStatus.podStateManager.address.toString() + omnipod_pod_expiry.text = podStateManager.expiryDateAsString + omnipodPumpStatus.podNumber = podStateManager.address.toString() var podDeviceState = omnipodPumpStatus.podDeviceState @@ -327,13 +329,13 @@ class OmnipodFragment : DaggerFragment() { } } - if (omnipodPumpStatus.podStateManager.isSetupCompleted) { - if (omnipodPumpStatus.podStateManager.lastDeliveryStatus != null) { - stateText += " (last delivery status: " + omnipodPumpStatus.podStateManager.lastDeliveryStatus.name + ")" + if (podStateManager.isSetupCompleted) { + if (podStateManager.lastDeliveryStatus != null) { + stateText += " (last delivery status: " + podStateManager.lastDeliveryStatus.name + ")" } } else { - if (omnipodPumpStatus.podStateManager.isPaired) { - stateText += " (setup progress: " + omnipodPumpStatus.podStateManager.setupProgress.name + ")" + if (podStateManager.isPaired) { + stateText += " (setup progress: " + podStateManager.setupProgress.name + ")" } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java index 1b8db8f50f..49b7faa7fe 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java @@ -90,6 +90,7 @@ import io.reactivex.schedulers.Schedulers; public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPumpPluginInterface, RileyLinkPumpDevice { // TODO Dagger (maybe done) + @Inject protected PodStateManager podStateManager; private static OmnipodPumpPlugin plugin = null; private RileyLinkServiceData rileyLinkServiceData; private ServiceTaskExecutor serviceTaskExecutor; @@ -149,6 +150,7 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump PumpType.Insulet_Omnipod, injector, resourceHelper, aapsLogger, commandQueue, rxBus, activePlugin, sp, context, fabricPrivacy ); + injector.androidInjector().inject(this); this.rileyLinkServiceData = rileyLinkServiceData; this.serviceTaskExecutor = serviceTaskExecutor; @@ -197,6 +199,10 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump if (isOmnipodEros) { + // We can't do this in PodStateManager itself, because JodaTimeAndroid.init() hasn't been called yet + // When PodStateManager is created, which causes an IllegalArgumentException for DateTimeZones not being recognized + podStateManager.loadPodState(); + serviceConnection = new ServiceConnection() { @Override @@ -486,8 +492,8 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump @Override public boolean isSuspended() { - return (omnipodUtil.getDriverState() == OmnipodDriverState.Initalized_NoPod) || - (omnipodUtil.getPodStateManager().hasState() && omnipodUtil.getPodStateManager().isSuspended()); + return omnipodUtil.getDriverState() == OmnipodDriverState.Initalized_NoPod || + !podStateManager.isSetupCompleted() || podStateManager.isSuspended(); // return (pumpStatusLocal != null && !pumpStatusLocal.podAvailable) || // (omnipodUtil.getPodStateManager().hasState() && OmnipodUtil.getPodStateManager().isSuspended()); @@ -613,8 +619,6 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump private void initializePump(boolean realInit) { - - aapsLogger.info(LTag.PUMP, getLogPrefix() + "initializePump - start"); // TODO ccc @@ -622,7 +626,6 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump setRefreshButtonEnabled(false); - PodStateManager podStateManager = omnipodUtil.getPodStateManager(); if (podStateManager.isPaired()) { aapsLogger.debug(LTag.PUMP, "PodStateManager (saved): " + podStateManager); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateManager.java index 1956c696ac..4cbb965244 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateManager.java @@ -6,6 +6,8 @@ import com.google.gson.JsonDeserializer; import com.google.gson.JsonPrimitive; import com.google.gson.JsonSerializer; +import net.danlew.android.joda.JodaTimeAndroid; + import org.apache.commons.lang3.StringUtils; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/PodManagementActivity.kt b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/PodManagementActivity.kt index c80fa1462b..b03332828a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/PodManagementActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/PodManagementActivity.kt @@ -15,6 +15,7 @@ import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction import info.nightscout.androidaps.plugins.pump.omnipod.defs.SetupProgress +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.defs.PodActionType import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.model.FullInitPodWizardModel import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.model.RemovePodWizardModel @@ -42,6 +43,7 @@ class PodManagementActivity : NoSplashAppCompatActivity() { @Inject lateinit var fabricPrivacy: FabricPrivacy @Inject lateinit var commandQueue: CommandQueueProvider @Inject lateinit var omnipodUtil: OmnipodUtil + @Inject lateinit var podStateManager: PodStateManager @Inject lateinit var injector: HasAndroidInjector private var initPodChanged = false @@ -98,7 +100,6 @@ class PodManagementActivity : NoSplashAppCompatActivity() { wizardPagerContext.clearContext() wizardPagerContext.pagerSettings = pagerSettings - val podStateManager = omnipodUtil.getPodStateManager() val isFullInit = !podStateManager.isPaired || podStateManager.setupProgress.isBefore(SetupProgress.PRIMING_FINISHED) if (isFullInit) { wizardPagerContext.wizardModel = FullInitPodWizardModel(applicationContext) @@ -150,11 +151,11 @@ class PodManagementActivity : NoSplashAppCompatActivity() { } fun refreshButtons() { - initpod_init_pod.isEnabled = !omnipodUtil.podStateManager.isPaired() || - omnipodUtil.getPodStateManager().getSetupProgress().isBefore(SetupProgress.COMPLETED) + initpod_init_pod.isEnabled = !podStateManager.isPaired() || + podStateManager.getSetupProgress().isBefore(SetupProgress.COMPLETED) - initpod_remove_pod.isEnabled = omnipodUtil.podStateManager.hasState() && omnipodUtil.podStateManager.isPaired - initpod_reset_pod.isEnabled = omnipodUtil.podStateManager.hasState() + initpod_remove_pod.isEnabled = podStateManager.hasState() && podStateManager.isPaired + initpod_reset_pod.isEnabled = podStateManager.hasState() if (omnipodUtil.getDriverState() == OmnipodDriverState.NotInitalized) { // if rileylink is not running we disable all operations diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/pages/InitPodRefreshAction.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/pages/InitPodRefreshAction.java index d6b9734233..3d3d5d02d5 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/pages/InitPodRefreshAction.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/pages/InitPodRefreshAction.java @@ -16,6 +16,7 @@ import info.nightscout.androidaps.logging.AAPSLogger; import info.nightscout.androidaps.logging.LTag; import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; import info.nightscout.androidaps.plugins.pump.omnipod.defs.SetupProgress; +import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.PodManagementActivity; import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.defs.PodActionType; import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodDriverState; @@ -33,6 +34,7 @@ public class InitPodRefreshAction extends AbstractCancelAction implements Finish private PodActionType actionType; @Inject OmnipodUtil omnipodUtil; + @Inject PodStateManager podStateManager; @Inject AAPSLogger aapsLogger; @Inject SP sp; @@ -58,7 +60,7 @@ public class InitPodRefreshAction extends AbstractCancelAction implements Finish @Override public void execute() { if (actionType == PodActionType.InitPod) { - if (omnipodUtil.getPodStateManager().getSetupProgress().isBefore(SetupProgress.COMPLETED)) { + if (podStateManager.getSetupProgress().isBefore(SetupProgress.COMPLETED)) { omnipodUtil.setDriverState(OmnipodDriverState.Initalized_PodInitializing); } else { omnipodUtil.setDriverState(OmnipodDriverState.Initalized_PodAttached); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/pages/PodInfoFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/pages/PodInfoFragment.java index 9f8df4a783..a0369832bd 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/pages/PodInfoFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/pages/PodInfoFragment.java @@ -30,6 +30,7 @@ public class PodInfoFragment extends DaggerFragment { private static final String ARG_KEY = "key"; @Inject OmnipodUtil omnipodUtil; + @Inject PodStateManager podStateManager; private PageFragmentCallbacks mCallbacks; private String mKey; @@ -84,9 +85,6 @@ public class PodInfoFragment extends DaggerFragment { } private boolean createDataOfPod() { - - PodStateManager podStateManager = omnipodUtil.getPodStateManager(); - if (podStateManager == null) return false; @@ -96,7 +94,7 @@ public class PodInfoFragment extends DaggerFragment { if (podStateManager.getLot() != null) { mCurrentReviewItems.add(new ReviewItem("LOT", "" + podStateManager.getLot(), "35")); } - if(podStateManager.getTid() != null) { + if (podStateManager.getTid() != null) { mCurrentReviewItems.add(new ReviewItem("TID", "" + podStateManager.getLot(), "36")); } if (podStateManager.getPiVersion() != null) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/OmnipodPumpStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/OmnipodPumpStatus.java index e01acd7d9c..232fde6da1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/OmnipodPumpStatus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/OmnipodPumpStatus.java @@ -16,7 +16,6 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLin import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice; import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpDeviceState; import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodDeviceState; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodDeviceStatusChange; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; import info.nightscout.androidaps.utils.resources.ResourceHelper; @@ -46,7 +45,6 @@ public class OmnipodPumpStatus extends PumpStatus { public Double tempBasalAmount = 0.0d; public Integer tempBasalLength; public long tempBasalPumpId; - public PodStateManager podStateManager; public PumpType pumpType; public String regexMac = "([\\da-fA-F]{1,2}(?:\\:|$)){6}"; @@ -141,7 +139,6 @@ public class OmnipodPumpStatus extends PumpStatus { ", tempBasalEnd=" + tempBasalEnd + ", tempBasalAmount=" + tempBasalAmount + ", tempBasalLength=" + tempBasalLength + - ", podStateManager=" + podStateManager + ", regexMac='" + regexMac + '\'' + ", podNumber='" + podNumber + '\'' + ", podDeviceState=" + podDeviceState + diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java index 1d365c6dba..d5f8c95d72 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java @@ -9,6 +9,9 @@ import java.util.Date; import java.util.List; import java.util.Objects; +import javax.inject.Inject; +import javax.inject.Singleton; + import info.nightscout.androidaps.R; import info.nightscout.androidaps.events.Event; import info.nightscout.androidaps.events.EventRefreshOverview; @@ -21,24 +24,23 @@ import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertType; import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus; import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodAcknowledgeAlertsChanged; +import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodDeviceStatusChange; import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodPumpValuesChanged; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil; import info.nightscout.androidaps.utils.resources.ResourceHelper; import info.nightscout.androidaps.utils.sharedPreferences.SP; +@Singleton public class AapsPodStateManager extends PodStateManager { - private final AAPSLogger aapsLogger; private final SP sp; - private final OmnipodUtil omnipodUtil; private final OmnipodPumpStatus omnipodPumpStatus; private final RxBusWrapper rxBus; private final ResourceHelper resourceHelper; - public AapsPodStateManager(AAPSLogger aapsLogger, SP sp, OmnipodUtil omnipodUtil, - OmnipodPumpStatus omnipodPumpStatus, RxBusWrapper rxBus, - ResourceHelper resourceHelper) { + @Inject + public AapsPodStateManager(AAPSLogger aapsLogger, SP sp, OmnipodPumpStatus omnipodPumpStatus, + RxBusWrapper rxBus, ResourceHelper resourceHelper) { super(aapsLogger); if (aapsLogger == null) { @@ -47,9 +49,6 @@ public class AapsPodStateManager extends PodStateManager { if (sp == null) { throw new IllegalArgumentException("sp can not be null"); } - if (omnipodUtil == null) { - throw new IllegalArgumentException("omnipodUtil can not be null"); - } if (omnipodPumpStatus == null) { throw new IllegalArgumentException("omnipodPumpStatus can not be null"); } @@ -62,7 +61,6 @@ public class AapsPodStateManager extends PodStateManager { this.aapsLogger = aapsLogger; this.sp = sp; - this.omnipodUtil = omnipodUtil; this.omnipodPumpStatus = omnipodPumpStatus; this.rxBus = rxBus; this.resourceHelper = resourceHelper; @@ -80,58 +78,56 @@ public class AapsPodStateManager extends PodStateManager { @Override protected void notifyPodStateChanged() { - if (omnipodPumpStatus != null) { - if (!hasState()) { - omnipodPumpStatus.ackAlertsText = null; - omnipodPumpStatus.ackAlertsAvailable = false; - omnipodPumpStatus.lastBolusTime = null; - omnipodPumpStatus.lastBolusAmount = null; - omnipodPumpStatus.reservoirRemainingUnits = 0.0; - omnipodPumpStatus.pumpStatusType = PumpStatusType.Suspended; - sendEvent(new EventOmnipodAcknowledgeAlertsChanged()); - sendEvent(new EventOmnipodPumpValuesChanged()); - sendEvent(new EventRefreshOverview("Omnipod Pump", false)); - } else { - // Update active alerts - if (hasActiveAlerts()) { - List alerts = getTranslatedActiveAlerts(); - String alertsText = TextUtils.join("\n", alerts); + if (!hasState()) { + omnipodPumpStatus.ackAlertsText = null; + omnipodPumpStatus.ackAlertsAvailable = false; + omnipodPumpStatus.lastBolusTime = null; + omnipodPumpStatus.lastBolusAmount = null; + omnipodPumpStatus.reservoirRemainingUnits = 0.0; + omnipodPumpStatus.pumpStatusType = PumpStatusType.Suspended; + sendEvent(new EventOmnipodAcknowledgeAlertsChanged()); + sendEvent(new EventOmnipodPumpValuesChanged()); + sendEvent(new EventRefreshOverview("Omnipod Pump", false)); + } else { + // Update active alerts + if (hasActiveAlerts()) { + List alerts = getTranslatedActiveAlerts(); + String alertsText = TextUtils.join("\n", alerts); - if (!omnipodPumpStatus.ackAlertsAvailable || !alertsText.equals(omnipodPumpStatus.ackAlertsText)) { - omnipodPumpStatus.ackAlertsAvailable = true; - omnipodPumpStatus.ackAlertsText = TextUtils.join("\n", alerts); + if (!omnipodPumpStatus.ackAlertsAvailable || !alertsText.equals(omnipodPumpStatus.ackAlertsText)) { + omnipodPumpStatus.ackAlertsAvailable = true; + omnipodPumpStatus.ackAlertsText = TextUtils.join("\n", alerts); - sendEvent(new EventOmnipodAcknowledgeAlertsChanged()); - } - } else { - if (omnipodPumpStatus.ackAlertsAvailable || StringUtils.isNotEmpty(omnipodPumpStatus.ackAlertsText)) { - omnipodPumpStatus.ackAlertsText = null; - omnipodPumpStatus.ackAlertsAvailable = false; - sendEvent(new EventOmnipodAcknowledgeAlertsChanged()); - } + sendEvent(new EventOmnipodAcknowledgeAlertsChanged()); } + } else { + if (omnipodPumpStatus.ackAlertsAvailable || StringUtils.isNotEmpty(omnipodPumpStatus.ackAlertsText)) { + omnipodPumpStatus.ackAlertsText = null; + omnipodPumpStatus.ackAlertsAvailable = false; + sendEvent(new EventOmnipodAcknowledgeAlertsChanged()); + } + } - Date lastBolusStartTime = getLastBolusStartTime() == null ? null : getLastBolusStartTime().toDate(); - Double lastBolusAmount = getLastBolusAmount(); + Date lastBolusStartTime = getLastBolusStartTime() == null ? null : getLastBolusStartTime().toDate(); + Double lastBolusAmount = getLastBolusAmount(); - // Update other info: last bolus, units remaining, suspended - if (Objects.equals(lastBolusStartTime, omnipodPumpStatus.lastBolusTime) // - || !Objects.equals(lastBolusAmount, omnipodPumpStatus.lastBolusAmount) // - || !isReservoirStatusUpToDate(omnipodPumpStatus, getReservoirLevel()) - || isSuspended() != PumpStatusType.Suspended.equals(omnipodPumpStatus.pumpStatusType)) { - omnipodPumpStatus.lastBolusTime = lastBolusStartTime; - omnipodPumpStatus.lastBolusAmount = lastBolusAmount; - omnipodPumpStatus.reservoirRemainingUnits = getReservoirLevel() == null ? 75.0 : getReservoirLevel(); - omnipodPumpStatus.pumpStatusType = isSuspended() ? PumpStatusType.Suspended : PumpStatusType.Running; - sendEvent(new EventOmnipodPumpValuesChanged()); + // Update other info: last bolus, units remaining, suspended + if (Objects.equals(lastBolusStartTime, omnipodPumpStatus.lastBolusTime) // + || !Objects.equals(lastBolusAmount, omnipodPumpStatus.lastBolusAmount) // + || !isReservoirStatusUpToDate(omnipodPumpStatus, getReservoirLevel()) + || isSuspended() != PumpStatusType.Suspended.equals(omnipodPumpStatus.pumpStatusType)) { + omnipodPumpStatus.lastBolusTime = lastBolusStartTime; + omnipodPumpStatus.lastBolusAmount = lastBolusAmount; + omnipodPumpStatus.reservoirRemainingUnits = getReservoirLevel() == null ? 75.0 : getReservoirLevel(); + omnipodPumpStatus.pumpStatusType = isSuspended() ? PumpStatusType.Suspended : PumpStatusType.Running; + sendEvent(new EventOmnipodPumpValuesChanged()); - if (isSuspended() != PumpStatusType.Suspended.equals(omnipodPumpStatus.pumpStatusType)) { - sendEvent(new EventRefreshOverview("Omnipod Pump", false)); - } + if (isSuspended() != PumpStatusType.Suspended.equals(omnipodPumpStatus.pumpStatusType)) { + sendEvent(new EventRefreshOverview("Omnipod Pump", false)); } } } - omnipodUtil.notifyDeviceStatusChanged(); + rxBus.send(new EventOmnipodDeviceStatusChange(this)); } private List getTranslatedActiveAlerts() { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java index b2e4d0fc34..2503beb2b3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java @@ -7,6 +7,8 @@ import android.os.IBinder; import org.apache.commons.lang3.StringUtils; +import java.time.LocalDateTime; + import javax.inject.Inject; import info.nightscout.androidaps.R; @@ -26,9 +28,9 @@ import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunication import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus; import info.nightscout.androidaps.plugins.pump.omnipod.driver.comm.AapsOmnipodManager; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.comm.AapsPodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.driver.ui.OmnipodUIComm; import info.nightscout.androidaps.plugins.pump.omnipod.driver.ui.OmnipodUIPostprocessor; +import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodDeviceStatusChange; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil; @@ -43,6 +45,7 @@ public class RileyLinkOmnipodService extends RileyLinkService { @Inject OmnipodPumpStatus omnipodPumpStatus; @Inject OmnipodUtil omnipodUtil; @Inject OmnipodUIPostprocessor omnipodUIPostprocessor; + @Inject PodStateManager podStateManager; private static RileyLinkOmnipodService instance; @@ -60,12 +63,10 @@ public class RileyLinkOmnipodService extends RileyLinkService { instance = this; } - public static RileyLinkOmnipodService getInstance() { return instance; } - @Override public void onConfigurationChanged(Configuration newConfig) { aapsLogger.warn(LTag.PUMPCOMM, "onConfigurationChanged"); @@ -109,12 +110,7 @@ public class RileyLinkOmnipodService extends RileyLinkService { private void initializeErosOmnipodManager() { AapsOmnipodManager instance = AapsOmnipodManager.getInstance(); if (instance == null) { - PodStateManager podStateManager = new AapsPodStateManager(aapsLogger, sp, omnipodUtil, omnipodPumpStatus, rxBus, resourceHelper); - podStateManager.loadPodState(); - omnipodUtil.setPodStateManager(podStateManager); - OmnipodCommunicationManager omnipodCommunicationService = new OmnipodCommunicationManager(injector, rfspy); - //omnipodCommunicationService.setPumpStatus(omnipodPumpStatus); this.omnipodCommunicationManager = omnipodCommunicationService; aapsOmnipodManager = new AapsOmnipodManager(omnipodCommunicationService, podStateManager, omnipodPumpStatus, @@ -123,10 +119,9 @@ public class RileyLinkOmnipodService extends RileyLinkService { omnipodUIComm = new OmnipodUIComm(injector, aapsLogger, omnipodUtil, omnipodUIPostprocessor, aapsOmnipodManager); } else { - omnipodUtil.setPodStateManager(instance.getPodStateManager()); aapsOmnipodManager = instance; } - omnipodUtil.notifyDeviceStatusChanged(); + rxBus.send(new EventOmnipodDeviceStatusChange(podStateManager)); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodUtil.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodUtil.java index c88dd5dcdd..7fde7c640f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodUtil.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodUtil.java @@ -52,13 +52,13 @@ public class OmnipodUtil { private OmnipodPodType omnipodPodType; private OmnipodDriverState driverState = OmnipodDriverState.NotInitalized; - @Inject public OmnipodUtil( AAPSLogger aapsLogger, RxBusWrapper rxBus, RileyLinkUtil rileyLinkUtil, OmnipodPumpStatus omnipodPumpStatus, + PodStateManager podStateManager, SP sp, ActivePluginProvider activePlugins ) { @@ -70,22 +70,18 @@ public class OmnipodUtil { this.activePlugins = activePlugins; } - public boolean isLowLevelDebug() { return lowLevelDebug; } - public void setLowLevelDebug(boolean lowLevelDebug) { this.lowLevelDebug = lowLevelDebug; } - public OmnipodCommandType getCurrentCommand() { return currentCommand; } - public void setCurrentCommand(OmnipodCommandType currentCommand) { this.currentCommand = currentCommand; @@ -100,12 +96,10 @@ public class OmnipodUtil { MainApp.gs(R.string.omnipod_error_operation_not_possible_no_configuration), (Runnable) null); } - public OmnipodDriverState getDriverState() { return driverState; } - public void setDriverState(OmnipodDriverState state) { if (driverState == state) return; @@ -123,7 +117,6 @@ public class OmnipodUtil { // } } - private Gson createGson() { GsonBuilder gsonBuilder = new GsonBuilder() .registerTypeAdapter(DateTime.class, (JsonSerializer) (dateTime, typeOfSrc, context) -> @@ -138,16 +131,8 @@ public class OmnipodUtil { return gsonBuilder.create(); } - public void setPodStateManager(PodStateManager podStateManager) { - if (podStateManager == null) { - throw new IllegalArgumentException("Pod state manager can not be null"); - } - omnipodPumpStatus.podStateManager = podStateManager; - notifyDeviceStatusChanged(); - } - public void notifyDeviceStatusChanged() { - rxBus.send(new EventOmnipodDeviceStatusChange(omnipodPumpStatus.podStateManager)); + } @@ -155,41 +140,26 @@ public class OmnipodUtil { omnipodPumpStatus.podDeviceState = podDeviceState; } - public void setOmnipodPodType(OmnipodPodType omnipodPodType) { this.omnipodPodType = omnipodPodType; } - public OmnipodPodType getOmnipodPodType() { return this.omnipodPodType; } - public PodDeviceState getPodDeviceState() { return omnipodPumpStatus.podDeviceState; } - - public PodStateManager getPodStateManager() { - if (omnipodPumpStatus.podStateManager == null) { - aapsLogger.error("OmnipodUtil.getPodStateManager was called, but podStateManager is null"); - throw new IllegalStateException("Pod state manager is null"); - } - return omnipodPumpStatus.podStateManager; - } - - public boolean isOmnipodEros() { return this.activePlugins.getActivePump().model() == PumpType.Insulet_Omnipod; } - public boolean isOmnipodDash() { return this.activePlugins.getActivePump().model() == PumpType.Insulet_Omnipod_Dash; } - public void setPumpType(PumpType pumpType_) { omnipodPumpStatus.pumpType = pumpType_; } @@ -198,7 +168,6 @@ public class OmnipodUtil { return omnipodPumpStatus.pumpType; } - public Gson getGsonInstance() { return this.gsonInstance; } From e74e80a4cee4927cbd63ec9d6fd76f6b6ad89a74 Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Sun, 9 Aug 2020 19:11:00 +0200 Subject: [PATCH 15/17] Inject RileyLinkServiceData in SetPreamble command and remove some unused code --- .../plugins/pump/common/hw/rileylink/RileyLinkUtil.java | 7 ------- .../plugins/pump/common/hw/rileylink/ble/RFSpy.java | 2 +- .../pump/common/hw/rileylink/ble/command/SetPreamble.java | 3 ++- .../hw/rileylink/service/RileyLinkBroadcastReceiver.java | 2 +- .../common/hw/rileylink/service/RileyLinkServiceData.java | 2 -- 5 files changed, 4 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkUtil.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkUtil.java index ff524b2ed2..18e07f1e72 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkUtil.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/RileyLinkUtil.java @@ -38,9 +38,6 @@ public class RileyLinkUtil { private RileyLinkEncodingType encoding; private Encoding4b6b encoding4b6b; - // TODO maybe not needed - private RileyLinkTargetFrequency rileyLinkTargetFrequency; - @Inject public RileyLinkUtil() { } @@ -158,8 +155,4 @@ public class RileyLinkUtil { public Encoding4b6b getEncoding4b6b() { return encoding4b6b; } - - public void setRileyLinkTargetFrequency(RileyLinkTargetFrequency rileyLinkTargetFrequency_) { - this.rileyLinkTargetFrequency = rileyLinkTargetFrequency_; - } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpy.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpy.java index 702354a82e..71fc405748 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpy.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpy.java @@ -387,7 +387,7 @@ public class RFSpy { try { resp = writeToData(new SetPreamble(injector, preamble), EXPECTED_MAX_BLUETOOTH_LATENCY_MS); } catch (Exception e) { - e.toString(); + aapsLogger.error("Failed to set preamble", e); } return resp; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/SetPreamble.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/SetPreamble.java index d58525deb0..3e99a8e412 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/SetPreamble.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/command/SetPreamble.java @@ -18,10 +18,11 @@ public class SetPreamble extends RileyLinkCommand { private int preamble; - public SetPreamble(HasAndroidInjector injector, int preamble) throws Exception { super(); + injector.androidInjector().inject(this); + // this command was not supported before 2.0 if (!rileyLinkServiceData.firmwareVersion.isSameVersion(RileyLinkFirmwareVersion.Version2AndHigher)) { throw new NotImplementedException("Old firmware does not support SetPreamble command"); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkBroadcastReceiver.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkBroadcastReceiver.java index 4beea20154..5cec5ccccf 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkBroadcastReceiver.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkBroadcastReceiver.java @@ -150,7 +150,7 @@ public class RileyLinkBroadcastReceiver extends DaggerBroadcastReceiver { return true; } else if (action.equals(RileyLinkConst.Intents.RileyLinkReady)) { - aapsLogger.warn(LTag.PUMPCOMM, "MedtronicConst.Intents.RileyLinkReady"); + aapsLogger.warn(LTag.PUMPCOMM, "RileyLinkConst.Intents.RileyLinkReady"); // sendIPCNotification(RT2Const.IPC.MSG_note_WakingPump); rileyLinkService.rileyLinkBLE.enableNotifications(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.java index cac30e6de1..b2439546a7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.java @@ -67,12 +67,10 @@ public class RileyLinkServiceData { return workWithServiceState(null, null, false); } - public void setServiceState(RileyLinkServiceState newState, RileyLinkError errorCode) { workWithServiceState(newState, errorCode, true); } - private synchronized RileyLinkServiceState workWithServiceState(RileyLinkServiceState newState, RileyLinkError errorCode, boolean set) { if (set) { From 4724cf60482cfc1ce1177a1909de5003d7eef2d1 Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Sun, 9 Aug 2020 20:27:21 +0200 Subject: [PATCH 16/17] Fix AapsPodStateManagerTest --- .../defs/state/AapsPodStateManagerTest.java | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/AapsPodStateManagerTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/AapsPodStateManagerTest.java index 85d8dd897e..cd82ae9ea5 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/AapsPodStateManagerTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/AapsPodStateManagerTest.java @@ -5,21 +5,30 @@ import org.joda.time.DateTimeUtils; import org.joda.time.DateTimeZone; import org.joda.time.Duration; import org.junit.After; -import org.junit.Ignore; import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.Mock; +import org.powermock.modules.junit4.PowerMockRunner; -import dagger.android.HasAndroidInjector; +import info.nightscout.androidaps.logging.AAPSLogger; +import info.nightscout.androidaps.plugins.bus.RxBusWrapper; import info.nightscout.androidaps.plugins.pump.omnipod.defs.FirmwareVersion; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus; import info.nightscout.androidaps.plugins.pump.omnipod.driver.comm.AapsPodStateManager; +import info.nightscout.androidaps.utils.resources.ResourceHelper; +import info.nightscout.androidaps.utils.sharedPreferences.SP; import static org.junit.Assert.assertEquals; +@RunWith(PowerMockRunner.class) public class AapsPodStateManagerTest { - @Mock HasAndroidInjector hasAndroidInjector; + @Mock AAPSLogger aapsLogger; + @Mock SP sp; + @Mock OmnipodPumpStatus omnipodPumpStatus; + RxBusWrapper rxBus = new RxBusWrapper(); + @Mock ResourceHelper resourceHelper; @Test - @Ignore("Not Dagger compliant") // FIXME public void times() { DateTimeZone timeZone = DateTimeZone.UTC; DateTimeZone.setDefault(timeZone); @@ -28,7 +37,7 @@ public class AapsPodStateManagerTest { DateTimeUtils.setCurrentMillisFixed(now.getMillis()); - AapsPodStateManager podStateManager = new AapsPodStateManager(hasAndroidInjector); + AapsPodStateManager podStateManager = new AapsPodStateManager(aapsLogger, sp, omnipodPumpStatus, rxBus, resourceHelper); podStateManager.initState(0x0); podStateManager.setPairingParameters(0, 0, new FirmwareVersion(1, 1, 1), new FirmwareVersion(2, 2, 2), timeZone); @@ -38,7 +47,6 @@ public class AapsPodStateManagerTest { } @Test - @Ignore("Not Dagger compliant") // FIXME public void changeSystemTimeZoneWithoutChangingPodTimeZone() { DateTimeZone timeZone = DateTimeZone.UTC; DateTimeZone.setDefault(timeZone); @@ -47,7 +55,7 @@ public class AapsPodStateManagerTest { DateTimeUtils.setCurrentMillisFixed(now.getMillis()); - AapsPodStateManager podStateManager = new AapsPodStateManager(hasAndroidInjector); + AapsPodStateManager podStateManager = new AapsPodStateManager(aapsLogger, sp, omnipodPumpStatus, rxBus, resourceHelper); podStateManager.initState(0x0); podStateManager.setPairingParameters(0, 0, new FirmwareVersion(1, 1, 1), new FirmwareVersion(2, 2, 2), timeZone); @@ -62,7 +70,6 @@ public class AapsPodStateManagerTest { } @Test - @Ignore("Not Dagger compliant") // FIXME public void changeSystemTimeZoneAndChangePodTimeZone() { DateTimeZone timeZone = DateTimeZone.UTC; DateTimeZone.setDefault(timeZone); @@ -71,7 +78,7 @@ public class AapsPodStateManagerTest { DateTimeUtils.setCurrentMillisFixed(now.getMillis()); - AapsPodStateManager podStateManager = new AapsPodStateManager(hasAndroidInjector); + AapsPodStateManager podStateManager = new AapsPodStateManager(aapsLogger, sp, omnipodPumpStatus, rxBus, resourceHelper); podStateManager.initState(0x0); podStateManager.setPairingParameters(0, 0, new FirmwareVersion(1, 1, 1), new FirmwareVersion(2, 2, 2), timeZone); From 8ed802d91b7b62e111bf97c57e2976fe8b8f7db5 Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Sun, 9 Aug 2020 21:03:40 +0200 Subject: [PATCH 17/17] Improve information on Pod tab --- .../plugins/pump/omnipod/OmnipodFragment.kt | 96 +++++-------------- .../omnipod/driver/OmnipodPumpStatus.java | 1 + app/src/main/res/values/strings.xml | 8 +- 3 files changed, 28 insertions(+), 77 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt index ff44fd1d4d..e1c22dc78e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt @@ -22,10 +22,8 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLin import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyLinkStatusActivity import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodStatusRequest -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodDeviceState import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.PodManagementActivity -import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodDriverState import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodAcknowledgeAlertsChanged import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodDeviceStatusChange @@ -245,46 +243,30 @@ class OmnipodFragment : DaggerFragment() { aapsLogger.info(LTag.PUMP, "getDriverState: [driverState={}]", driverState) - // FIXME for displaying pod info, we should look at PodStateManager instead of this driverState, - // because that way, we can also show the Pod info when the RL isn't initialized yet - if (driverState == OmnipodDriverState.NotInitalized) { - omnipod_pod_address.text = resourceHelper.gs(R.string.omnipod_pod_name_no_info) + if (!podStateManager.hasState() || !podStateManager.isPaired) { + if (podStateManager.hasState()) { + omnipod_pod_address.text = podStateManager.address.toString() + } else { + omnipod_pod_address.text = "-" + } omnipod_pod_lot.text = "-" omnipod_pod_tid.text = "-" omnipod_pod_fw_version.text = "-" omnipod_pod_expiry.text = "-" - omnipod_pod_status.text = resourceHelper.gs(R.string.omnipod_pod_not_initalized) + if (podStateManager.hasState()) { + omnipod_pod_status.text = resourceHelper.gs(R.string.omnipod_pod_status_not_initalized) + } else { + omnipod_pod_status.text = resourceHelper.gs(R.string.omnipod_pod_status_no_pod_connected) + } omnipodPumpStatus.podAvailable = false omnipodPumpStatus.podNumber == null - } else if (driverState == OmnipodDriverState.Initalized_NoPod) { - omnipod_pod_address.text = resourceHelper.gs(R.string.omnipod_pod_name_no_info) - omnipod_pod_lot.text = "-" - omnipod_pod_tid.text = "-" - omnipod_pod_fw_version.text = "-" - omnipod_pod_expiry.text = "-" - omnipod_pod_status.text = resourceHelper.gs(R.string.omnipod_pod_no_pod_connected) - omnipodPumpStatus.podAvailable = false - omnipodPumpStatus.podNumber == null - } else if (driverState == OmnipodDriverState.Initalized_PodInitializing) { - omnipod_pod_address.text = podStateManager.address.toString() - omnipod_pod_lot.text = "-" - omnipod_pod_tid.text = "-" - omnipod_pod_fw_version.text = "-" - omnipod_pod_expiry.text = "-" - omnipod_pod_status.text = resourceHelper.gs(R.string.omnipod_pod_status_initalizing) + " (" + podStateManager.getSetupProgress().name + ")" - omnipodPumpStatus.podAvailable = false - omnipodPumpStatus.podNumber == podStateManager.address.toString() } else { omnipodPumpStatus.podLotNumber = "" + podStateManager.lot - omnipodPumpStatus.podAvailable = true + omnipodPumpStatus.podAvailable = podStateManager.isSetupCompleted omnipod_pod_address.text = podStateManager.address.toString() - omnipod_pod_lot.text = if (podStateManager.lot == null) "" else podStateManager.lot.toString() - omnipod_pod_tid.text = if (podStateManager.tid == null) "" else podStateManager.tid.toString() - if (podStateManager.pmVersion == null || podStateManager.piVersion == null) { - omnipod_pod_fw_version.text = "" - } else { - omnipod_pod_fw_version.text = podStateManager.pmVersion.toString() + " / " + podStateManager.piVersion.toString() - } + omnipod_pod_lot.text = podStateManager.lot.toString() + omnipod_pod_tid.text = podStateManager.tid.toString() + omnipod_pod_fw_version.text = podStateManager.pmVersion.toString() + " / " + podStateManager.piVersion.toString() omnipod_pod_expiry.text = podStateManager.expiryDateAsString omnipodPumpStatus.podNumber = podStateManager.address.toString() @@ -292,51 +274,17 @@ class OmnipodFragment : DaggerFragment() { var stateText: String? - // FIXME this PodDeviceState doesn't make much sense. We should use info from PodStateManager - when (podDeviceState) { - null, - PodDeviceState.Sleeping -> stateText = "{fa-bed} " // + pumpStatus.pumpDeviceState.name()); - PodDeviceState.NeverContacted, - PodDeviceState.WakingUp, - PodDeviceState.PumpUnreachable, - PodDeviceState.ErrorWhenCommunicating, - PodDeviceState.TimeoutWhenCommunicating, - PodDeviceState.InvalidConfiguration -> stateText = " " + resourceHelper.gs(podDeviceState.resourceId) - - PodDeviceState.Active -> { - stateText = resourceHelper.gs(R.string.omnipod_pod_status_active) -// val cmd = OmnipodUtil.getCurrentCommand() -// if (cmd == null) -// omnipod_pod_status.text = " " + resourceHelper.gs(pumpStatus.pumpDeviceState.resourceId) -// else { -// aapsLogger.debug(LTag.PUMP,"Command: " + cmd) -// val cmdResourceId = cmd.resourceId -// if (cmd == MedtronicCommandType.GetHistoryData) { -// omnipod_pod_status.text = OmnipodUtil.frameNumber?.let { -// resourceHelper.gs(cmdResourceId, OmnipodUtil.pageNumber, OmnipodUtil.frameNumber) -// } -// ?: resourceHelper.gs(R.string.medtronic_cmd_desc_get_history_request, OmnipodUtil.pageNumber) -// } else { -// omnipod_pod_status.text = " " + (cmdResourceId?.let { resourceHelper.gs(it) } -// ?: cmd.getCommandDescription()) -// } -// } - } - - else -> { - aapsLogger.warn(LTag.PUMP, "Unknown pump state: " + omnipodPumpStatus.podDeviceState) - stateText = resourceHelper.gs(R.string.omnipod_pod_status_unknown) - } - } - - if (podStateManager.isSetupCompleted) { + if(podStateManager.hasFaultEvent()) { + val faultEventCode = podStateManager.faultEvent.faultEventCode + stateText = resourceHelper.gs(R.string.omnipod_pod_status_pod_fault) + " ("+ faultEventCode.value +" "+ faultEventCode.name +")" + } else if (podStateManager.isSetupCompleted) { + stateText = resourceHelper.gs(R.string.omnipod_pod_status_pod_running) if (podStateManager.lastDeliveryStatus != null) { stateText += " (last delivery status: " + podStateManager.lastDeliveryStatus.name + ")" } } else { - if (podStateManager.isPaired) { - stateText += " (setup progress: " + podStateManager.setupProgress.name + ")" - } + stateText = resourceHelper.gs(R.string.omnipod_pod_setup_in_progress) + stateText += " (setup progress: " + podStateManager.setupProgress.name + ")" } omnipod_pod_status.text = stateText diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/OmnipodPumpStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/OmnipodPumpStatus.java index 232fde6da1..e069875d27 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/OmnipodPumpStatus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/OmnipodPumpStatus.java @@ -51,6 +51,7 @@ public class OmnipodPumpStatus extends PumpStatus { public String podNumber; public PodDeviceState podDeviceState = PodDeviceState.NeverContacted; + // FIXME replace with method calls on PodStateManager public boolean podAvailable = false; public boolean podAvailibityChecked = false; public boolean ackAlertsAvailable = false; diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4c754140dc..73f101749e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1863,9 +1863,11 @@ Over 50 U Pod Address Pod Expires - No info - No Pod connected - Not initialized + No Pod connected + Pod setup in progress + Pod not initialized + !!! Pod Fault + Pod running Active Pod Alerts Ack Alerts %1$.2f %2$s (%3$s)