Merge pull request #129 from AAPS-Omnipod/omnipod_eros_dev_podstate

Rework Pod state management
This commit is contained in:
bartsopers 2020-08-09 21:06:39 +02:00 committed by GitHub
commit 4d04353e7b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
47 changed files with 1664 additions and 1286 deletions

View file

@ -1,9 +1,13 @@
package info.nightscout.androidaps.dependencyInjection package info.nightscout.androidaps.dependencyInjection
import dagger.Module import dagger.Module
import dagger.Provides
import dagger.android.ContributesAndroidInjector 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.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.PodHistoryActivity
import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.PodManagementActivity import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.PodManagementActivity
import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.initpod.InitActionFragment import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.initpod.InitActionFragment
@ -11,15 +15,21 @@ 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.InitPodRefreshAction
import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.pages.PodInfoFragment 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.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.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.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 @Module
@Suppress("unused") @Suppress("unused")
abstract class OmnipodModule { abstract class OmnipodModule {
// Activities // Activities
@ContributesAndroidInjector abstract fun contributesPodManagementActivity(): PodManagementActivity @ContributesAndroidInjector
abstract fun contributesPodManagementActivity(): PodManagementActivity
@ContributesAndroidInjector abstract fun contributesPodHistoryActivity(): PodHistoryActivity @ContributesAndroidInjector abstract fun contributesPodHistoryActivity(): PodHistoryActivity
// Fragments // Fragments
@ -28,13 +38,22 @@ abstract class OmnipodModule {
@ContributesAndroidInjector abstract fun podInfoFragment(): PodInfoFragment @ContributesAndroidInjector abstract fun podInfoFragment(): PodInfoFragment
// Service // Service
@ContributesAndroidInjector abstract fun omnipodCommunicationManagerProvider(): OmnipodCommunicationManager @ContributesAndroidInjector
abstract fun omnipodCommunicationManagerProvider(): OmnipodCommunicationManager
@ContributesAndroidInjector abstract fun aapsOmnipodManagerProvider(): AapsOmnipodManager @ContributesAndroidInjector abstract fun aapsOmnipodManagerProvider(): AapsOmnipodManager
// Data // Data
@ContributesAndroidInjector abstract fun omnipodUITaskProvider(): OmnipodUITask @ContributesAndroidInjector abstract fun omnipodUITaskProvider(): OmnipodUITask
@ContributesAndroidInjector abstract fun initPodRefreshAction(): InitPodRefreshAction @ContributesAndroidInjector abstract fun initPodRefreshAction(): InitPodRefreshAction
@ContributesAndroidInjector abstract fun podSessionState(): PodSessionState @ContributesAndroidInjector abstract fun podStateManager(): PodStateManager
@ContributesAndroidInjector abstract fun initPodTask(): InitPodTask @ContributesAndroidInjector abstract fun initPodTask(): InitPodTask
@ContributesAndroidInjector abstract fun omnipodPumpPlugin(): OmnipodPumpPlugin
companion object {
@Provides
@Singleton
fun podStateManagerProvider(aapsLogger: AAPSLogger, sp: SP, omnipodPumpStatus: OmnipodPumpStatus,
rxBus: RxBusWrapper, resourceHelper: ResourceHelper): PodStateManager =
AapsPodStateManager(aapsLogger, sp, omnipodPumpStatus, rxBus, resourceHelper)
}
} }

View file

@ -38,9 +38,6 @@ public class RileyLinkUtil {
private RileyLinkEncodingType encoding; private RileyLinkEncodingType encoding;
private Encoding4b6b encoding4b6b; private Encoding4b6b encoding4b6b;
// TODO maybe not needed
private RileyLinkTargetFrequency rileyLinkTargetFrequency;
@Inject @Inject
public RileyLinkUtil() { public RileyLinkUtil() {
} }
@ -158,8 +155,4 @@ public class RileyLinkUtil {
public Encoding4b6b getEncoding4b6b() { public Encoding4b6b getEncoding4b6b() {
return encoding4b6b; return encoding4b6b;
} }
public void setRileyLinkTargetFrequency(RileyLinkTargetFrequency rileyLinkTargetFrequency_) {
this.rileyLinkTargetFrequency = rileyLinkTargetFrequency_;
}
} }

View file

@ -387,7 +387,7 @@ public class RFSpy {
try { try {
resp = writeToData(new SetPreamble(injector, preamble), EXPECTED_MAX_BLUETOOTH_LATENCY_MS); resp = writeToData(new SetPreamble(injector, preamble), EXPECTED_MAX_BLUETOOTH_LATENCY_MS);
} catch (Exception e) { } catch (Exception e) {
e.toString(); aapsLogger.error("Failed to set preamble", e);
} }
return resp; return resp;
} }

View file

@ -18,10 +18,11 @@ public class SetPreamble extends RileyLinkCommand {
private int preamble; private int preamble;
public SetPreamble(HasAndroidInjector injector, int preamble) throws Exception { public SetPreamble(HasAndroidInjector injector, int preamble) throws Exception {
super(); super();
injector.androidInjector().inject(this);
// this command was not supported before 2.0 // this command was not supported before 2.0
if (!rileyLinkServiceData.firmwareVersion.isSameVersion(RileyLinkFirmwareVersion.Version2AndHigher)) { if (!rileyLinkServiceData.firmwareVersion.isSameVersion(RileyLinkFirmwareVersion.Version2AndHigher)) {
throw new NotImplementedException("Old firmware does not support SetPreamble command"); throw new NotImplementedException("Old firmware does not support SetPreamble command");

View file

@ -150,7 +150,7 @@ public class RileyLinkBroadcastReceiver extends DaggerBroadcastReceiver {
return true; return true;
} else if (action.equals(RileyLinkConst.Intents.RileyLinkReady)) { } 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); // sendIPCNotification(RT2Const.IPC.MSG_note_WakingPump);
rileyLinkService.rileyLinkBLE.enableNotifications(); rileyLinkService.rileyLinkBLE.enableNotifications();

View file

@ -67,12 +67,10 @@ public class RileyLinkServiceData {
return workWithServiceState(null, null, false); return workWithServiceState(null, null, false);
} }
public void setServiceState(RileyLinkServiceState newState, RileyLinkError errorCode) { public void setServiceState(RileyLinkServiceState newState, RileyLinkError errorCode) {
workWithServiceState(newState, errorCode, true); workWithServiceState(newState, errorCode, true);
} }
private synchronized RileyLinkServiceState workWithServiceState(RileyLinkServiceState newState, RileyLinkError errorCode, boolean set) { private synchronized RileyLinkServiceState workWithServiceState(RileyLinkServiceState newState, RileyLinkError errorCode, boolean set) {
if (set) { if (set) {

View file

@ -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.dialog.RileyLinkStatusActivity
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData
import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodStatusRequest 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.defs.SetupProgress
import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.PodManagementActivity 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.driver.OmnipodPumpStatus
import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodAcknowledgeAlertsChanged 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.EventOmnipodDeviceStatusChange
@ -61,6 +59,7 @@ class OmnipodFragment : DaggerFragment() {
@Inject lateinit var omnipodPumpPlugin: OmnipodPumpPlugin @Inject lateinit var omnipodPumpPlugin: OmnipodPumpPlugin
@Inject lateinit var warnColors: WarnColors @Inject lateinit var warnColors: WarnColors
@Inject lateinit var omnipodPumpStatus: OmnipodPumpStatus @Inject lateinit var omnipodPumpStatus: OmnipodPumpStatus
@Inject lateinit var podStateManager: PodStateManager
@Inject lateinit var sp: SP @Inject lateinit var sp: SP
@Inject lateinit var omnipodUtil: OmnipodUtil @Inject lateinit var omnipodUtil: OmnipodUtil
@Inject lateinit var rileyLinkServiceData: RileyLinkServiceData @Inject lateinit var rileyLinkServiceData: RileyLinkServiceData
@ -209,14 +208,8 @@ class OmnipodFragment : DaggerFragment() {
@Synchronized @Synchronized
private fun setDeviceStatus(event: EventOmnipodDeviceStatusChange) { private fun setDeviceStatus(event: EventOmnipodDeviceStatusChange) {
} }
@Synchronized @Synchronized
private fun setDeviceStatus() { private fun setDeviceStatus() {
//val omnipodPumpStatus: OmnipodPumpStatus = OmnipodUtil.getPumpStatus() //val omnipodPumpStatus: OmnipodPumpStatus = OmnipodUtil.getPumpStatus()
@ -250,81 +243,48 @@ class OmnipodFragment : DaggerFragment() {
aapsLogger.info(LTag.PUMP, "getDriverState: [driverState={}]", driverState) aapsLogger.info(LTag.PUMP, "getDriverState: [driverState={}]", driverState)
if (driverState == OmnipodDriverState.NotInitalized) { if (!podStateManager.hasState() || !podStateManager.isPaired) {
omnipod_pod_address.text = resourceHelper.gs(R.string.omnipod_pod_name_no_info) if (podStateManager.hasState()) {
omnipod_pod_expiry.text = "-" omnipod_pod_address.text = podStateManager.address.toString()
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_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.podSessionState.address.toString()
omnipod_pod_expiry.text = "-"
omnipod_pod_status.text = resourceHelper.gs(R.string.omnipod_pod_status_initalizing) + " (" + omnipodPumpStatus.podSessionState.getSetupProgress().name + ")"
omnipodPumpStatus.podAvailable = false
omnipodPumpStatus.podNumber == omnipodPumpStatus.podSessionState.address.toString()
} else { } else {
omnipodPumpStatus.podLotNumber = "" + omnipodPumpStatus.podSessionState.lot omnipod_pod_address.text = "-"
omnipodPumpStatus.podAvailable = true }
omnipod_pod_address.text = omnipodPumpStatus.podSessionState.address.toString() omnipod_pod_lot.text = "-"
omnipod_pod_expiry.text = omnipodPumpStatus.podSessionState.expiryDateAsString omnipod_pod_tid.text = "-"
omnipodPumpStatus.podNumber = omnipodPumpStatus.podSessionState.address.toString() omnipod_pod_fw_version.text = "-"
omnipod_pod_expiry.text = "-"
//pumpStatus.podSessionState = checkStatusSet(pumpStatus.podSessionState, if (podStateManager.hasState()) {
// OmnipodUtil.getPodSessionState()) as PodSessionState? 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 {
omnipodPumpStatus.podLotNumber = "" + podStateManager.lot
omnipodPumpStatus.podAvailable = podStateManager.isSetupCompleted
omnipod_pod_address.text = podStateManager.address.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()
var podDeviceState = omnipodPumpStatus.podDeviceState var podDeviceState = omnipodPumpStatus.podDeviceState
var stateText: String? var stateText: String?
when (podDeviceState) { if(podStateManager.hasFaultEvent()) {
null, val faultEventCode = podStateManager.faultEvent.faultEventCode
PodDeviceState.Sleeping -> stateText = "{fa-bed} " // + pumpStatus.pumpDeviceState.name()); stateText = resourceHelper.gs(R.string.omnipod_pod_status_pod_fault) + " ("+ faultEventCode.value +" "+ faultEventCode.name +")"
PodDeviceState.NeverContacted, } else if (podStateManager.isSetupCompleted) {
PodDeviceState.WakingUp, stateText = resourceHelper.gs(R.string.omnipod_pod_status_pod_running)
PodDeviceState.PumpUnreachable, if (podStateManager.lastDeliveryStatus != null) {
PodDeviceState.ErrorWhenCommunicating, stateText += " (last delivery status: " + podStateManager.lastDeliveryStatus.name + ")"
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 (SetupProgress.COMPLETED.equals(omnipodPumpStatus.podSessionState.getSetupProgress())) {
if(omnipodPumpStatus.podSessionState.lastDeliveryStatus != null) {
stateText += " (last delivery status: " + omnipodPumpStatus.podSessionState.lastDeliveryStatus.name + ")"
} }
} else { } else {
if(omnipodPumpStatus.podSessionState.setupProgress != null) { stateText = resourceHelper.gs(R.string.omnipod_pod_setup_in_progress)
stateText += " (setup progress: " + omnipodPumpStatus.podSessionState.setupProgress.name + ")" stateText += " (setup progress: " + podStateManager.setupProgress.name + ")"
}
} }
omnipod_pod_status.text = stateText omnipod_pod_status.text = stateText

View file

@ -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.PumpPluginAbstract;
import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus; 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.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.PumpDriverState;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst; 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.OmnipodCustomActionType;
import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodPumpPluginInterface; 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.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.OmnipodDriverState;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus; import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.ui.OmnipodUIComm; import info.nightscout.androidaps.plugins.pump.omnipod.driver.ui.OmnipodUIComm;
@ -91,6 +90,7 @@ import io.reactivex.schedulers.Schedulers;
public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPumpPluginInterface, RileyLinkPumpDevice { public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPumpPluginInterface, RileyLinkPumpDevice {
// TODO Dagger (maybe done) // TODO Dagger (maybe done)
@Inject protected PodStateManager podStateManager;
private static OmnipodPumpPlugin plugin = null; private static OmnipodPumpPlugin plugin = null;
private RileyLinkServiceData rileyLinkServiceData; private RileyLinkServiceData rileyLinkServiceData;
private ServiceTaskExecutor serviceTaskExecutor; private ServiceTaskExecutor serviceTaskExecutor;
@ -150,6 +150,7 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump
PumpType.Insulet_Omnipod, PumpType.Insulet_Omnipod,
injector, resourceHelper, aapsLogger, commandQueue, rxBus, activePlugin, sp, context, fabricPrivacy injector, resourceHelper, aapsLogger, commandQueue, rxBus, activePlugin, sp, context, fabricPrivacy
); );
injector.androidInjector().inject(this);
this.rileyLinkServiceData = rileyLinkServiceData; this.rileyLinkServiceData = rileyLinkServiceData;
this.serviceTaskExecutor = serviceTaskExecutor; this.serviceTaskExecutor = serviceTaskExecutor;
@ -198,6 +199,10 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump
if (isOmnipodEros) { 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() { serviceConnection = new ServiceConnection() {
@Override @Override
@ -487,18 +492,18 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump
@Override @Override
public boolean isSuspended() { public boolean isSuspended() {
return (omnipodUtil.getDriverState() == OmnipodDriverState.Initalized_NoPod) || return omnipodUtil.getDriverState() == OmnipodDriverState.Initalized_NoPod ||
(omnipodUtil.getPodSessionState() != null && omnipodUtil.getPodSessionState().isSuspended()); !podStateManager.isSetupCompleted() || podStateManager.isSuspended();
// return (pumpStatusLocal != null && !pumpStatusLocal.podAvailable) || // return (pumpStatusLocal != null && !pumpStatusLocal.podAvailable) ||
// (OmnipodUtil.getPodSessionState() != null && OmnipodUtil.getPodSessionState().isSuspended()); // (omnipodUtil.getPodStateManager().hasState() && OmnipodUtil.getPodStateManager().isSuspended());
// //
// TODO ddd // TODO ddd
// return (OmnipodUtil.getDriverState() == OmnipodDriverState.Initalized_NoPod) || // return (OmnipodUtil.getDriverState() == OmnipodDriverState.Initalized_NoPod) ||
// (OmnipodUtil.getPodSessionState() != null && OmnipodUtil.getPodSessionState().isSuspended()); // (omnipodUtil.getPodStateManager().hasState() && OmnipodUtil.getPodStateManager().isSuspended());
// //
// return (pumpStatusLocal != null && !pumpStatusLocal.podAvailable) || // return (pumpStatusLocal != null && !pumpStatusLocal.podAvailable) ||
// (OmnipodUtil.getPodSessionState() != null && OmnipodUtil.getPodSessionState().isSuspended()); // (omnipodUtil.getPodStateManager().hasState() && OmnipodUtil.getPodStateManager().isSuspended());
} }
@Override @Override
@ -580,6 +585,7 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump
//getPodPumpStatusObject().driverState = OmnipodDriverState.Initalized_PodAvailable; //getPodPumpStatusObject().driverState = OmnipodDriverState.Initalized_PodAvailable;
//driverState = OmnipodDriverState.Initalized_PodAvailable; //driverState = OmnipodDriverState.Initalized_PodAvailable;
// FIXME this does not seem to make sense
omnipodUtil.setDriverState(OmnipodDriverState.Initalized_PodAttached); omnipodUtil.setDriverState(OmnipodDriverState.Initalized_PodAttached);
// we would probably need to read Basal Profile here too // we would probably need to read Basal Profile here too
} }
@ -613,8 +619,6 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump
private void initializePump(boolean realInit) { private void initializePump(boolean realInit) {
aapsLogger.info(LTag.PUMP, getLogPrefix() + "initializePump - start"); aapsLogger.info(LTag.PUMP, getLogPrefix() + "initializePump - start");
// TODO ccc // TODO ccc
@ -622,17 +626,8 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump
setRefreshButtonEnabled(false); setRefreshButtonEnabled(false);
PodSessionState podSessionState = null; if (podStateManager.isPaired()) {
aapsLogger.debug(LTag.PUMP, "PodStateManager (saved): " + podStateManager);
if (omnipodUtil.getPodSessionState() != null) {
podSessionState = omnipodUtil.getPodSessionState();
} else {
podSessionState = omnipodUtil.loadSessionState();
}
if (podSessionState != null) {
aapsLogger.debug(LTag.PUMP, "PodSessionState (saved): " + podSessionState);
if (!isRefresh) { if (!isRefresh) {
pumpState = PumpDriverState.Initialized; pumpState = PumpDriverState.Initialized;
@ -640,9 +635,8 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump
// TODO handle if session state too old // TODO handle if session state too old
getPodPumpStatus(); getPodPumpStatus();
} else { } else {
aapsLogger.debug(LTag.PUMP, "No PodSessionState found. Pod probably not running."); aapsLogger.debug(LTag.PUMP, "No Pod running");
omnipodUtil.setDriverState(OmnipodDriverState.Initalized_NoPod); omnipodUtil.setDriverState(OmnipodDriverState.Initalized_NoPod);
} }

View file

@ -1,5 +1,7 @@
package info.nightscout.androidaps.plugins.pump.omnipod.comm; package info.nightscout.androidaps.plugins.pump.omnipod.comm;
import org.joda.time.DateTime;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -16,11 +18,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.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.RLMessageType;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkBLEError; 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.common.utils.ByteUtil;
import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpDeviceState; 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.action.OmnipodAction;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.CommunicationException; import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.CommunicationException;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalMessageAddressException; import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalMessageAddressException;
@ -43,7 +42,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.MessageBlockType;
import info.nightscout.androidaps.plugins.pump.omnipod.defs.PacketType; 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.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.driver.OmnipodPumpStatus;
import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException; import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException;
import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst;
@ -103,13 +102,13 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager {
this.omnipodPumpStatus.setPumpDeviceState(pumpDeviceState); this.omnipodPumpStatus.setPumpDeviceState(pumpDeviceState);
} }
public <T extends MessageBlock> T sendCommand(Class<T> responseClass, PodState podState, MessageBlock command) { public <T extends MessageBlock> T sendCommand(Class<T> responseClass, PodStateManager podStateManager, MessageBlock command) {
return sendCommand(responseClass, podState, command, true); return sendCommand(responseClass, podStateManager, command, true);
} }
public <T extends MessageBlock> T sendCommand(Class<T> responseClass, PodState podState, MessageBlock command, boolean automaticallyResyncNone) { public <T extends MessageBlock> T sendCommand(Class<T> responseClass, PodStateManager podStateManager, MessageBlock command, boolean automaticallyResyncNone) {
OmnipodMessage message = new OmnipodMessage(podState.getAddress(), Collections.singletonList(command), podState.getMessageNumber()); OmnipodMessage message = new OmnipodMessage(podStateManager.getAddress(), Collections.singletonList(command), podStateManager.getMessageNumber());
return exchangeMessages(responseClass, podState, message, automaticallyResyncNone); return exchangeMessages(responseClass, podStateManager, message, automaticallyResyncNone);
} }
// Convenience method // Convenience method
@ -117,70 +116,76 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager {
return action.execute(this); return action.execute(this);
} }
public <T extends MessageBlock> T exchangeMessages(Class<T> responseClass, PodState podState, OmnipodMessage message) { public <T extends MessageBlock> T exchangeMessages(Class<T> responseClass, PodStateManager podStateManager, OmnipodMessage message) {
return exchangeMessages(responseClass, podState, message, true); return exchangeMessages(responseClass, podStateManager, message, true);
} }
public <T extends MessageBlock> T exchangeMessages(Class<T> responseClass, PodState podState, OmnipodMessage message, boolean automaticallyResyncNonce) { public <T extends MessageBlock> T exchangeMessages(Class<T> responseClass, PodStateManager podStateManager, OmnipodMessage message, boolean automaticallyResyncNonce) {
return exchangeMessages(responseClass, podState, message, null, null, automaticallyResyncNonce); return exchangeMessages(responseClass, podStateManager, message, null, null, automaticallyResyncNonce);
} }
public synchronized <T extends MessageBlock> T exchangeMessages(Class<T> responseClass, PodState podState, OmnipodMessage message, Integer addressOverride, Integer ackAddressOverride) { public synchronized <T extends MessageBlock> T exchangeMessages(Class<T> responseClass, PodStateManager podStateManager, OmnipodMessage message, Integer addressOverride, Integer ackAddressOverride) {
return exchangeMessages(responseClass, podState, message, addressOverride, ackAddressOverride, true); return exchangeMessages(responseClass, podStateManager, message, addressOverride, ackAddressOverride, true);
} }
public synchronized <T extends MessageBlock> T exchangeMessages(Class<T> responseClass, PodState podState, OmnipodMessage message, Integer addressOverride, Integer ackAddressOverride, boolean automaticallyResyncNonce) { public synchronized <T extends MessageBlock> T exchangeMessages(Class<T> responseClass, PodStateManager podStateManager, OmnipodMessage message, Integer addressOverride, Integer ackAddressOverride, boolean automaticallyResyncNonce) {
aapsLogger.debug(LTag.PUMPCOMM, "Exchanging OmnipodMessage [responseClass={}, podState={}, message={}, addressOverride={}, ackAddressOverride={}, automaticallyResyncNonce={}]: {}", // aapsLogger.debug(LTag.PUMPCOMM, "Exchanging OmnipodMessage [responseClass={}, podStateManager={}, message={}, addressOverride={}, ackAddressOverride={}, automaticallyResyncNonce={}]: {}", //
responseClass.getSimpleName(), podState, message, addressOverride, ackAddressOverride, automaticallyResyncNonce, message); responseClass.getSimpleName(), podStateManager, message, addressOverride, ackAddressOverride, automaticallyResyncNonce, message);
for (int i = 0; 2 > i; i++) { for (int i = 0; 2 > i; i++) {
if (podState.hasNonceState() && message.isNonceResyncable()) { if (podStateManager.isPaired() && message.isNonceResyncable()) {
podState.advanceToNextNonce(); podStateManager.advanceToNextNonce();
} }
MessageBlock responseMessageBlock = transportMessages(podState, message, addressOverride, ackAddressOverride); MessageBlock responseMessageBlock = transportMessages(podStateManager, message, addressOverride, ackAddressOverride);
if (responseMessageBlock instanceof StatusResponse) { if (responseMessageBlock instanceof StatusResponse) {
podState.updateFromStatusResponse((StatusResponse) responseMessageBlock); podStateManager.updateFromStatusResponse((StatusResponse) responseMessageBlock);
} }
if (responseClass.isInstance(responseMessageBlock)) { if (responseClass.isInstance(responseMessageBlock)) {
podStateManager.setLastSuccessfulCommunication(DateTime.now());
return (T) responseMessageBlock; return (T) responseMessageBlock;
} else { } else {
if (responseMessageBlock.getType() == MessageBlockType.ERROR_RESPONSE) { if (responseMessageBlock.getType() == MessageBlockType.ERROR_RESPONSE) {
ErrorResponse error = (ErrorResponse) responseMessageBlock; ErrorResponse error = (ErrorResponse) responseMessageBlock;
if (error.getErrorResponseCode() == ErrorResponse.ERROR_RESPONSE_CODE_BAD_NONCE) { 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) { if (automaticallyResyncNonce) {
message.resyncNonce(podState.getCurrentNonce()); message.resyncNonce(podStateManager.getCurrentNonce());
} else { } else {
podStateManager.setLastFailedCommunication(DateTime.now());
throw new NonceOutOfSyncException(); throw new NonceOutOfSyncException();
} }
} else { } else {
podStateManager.setLastFailedCommunication(DateTime.now());
throw new PodReturnedErrorResponseException(error); throw new PodReturnedErrorResponseException(error);
} }
} else if (responseMessageBlock.getType() == MessageBlockType.POD_INFO_RESPONSE && ((PodInfoResponse) responseMessageBlock).getSubType() == PodInfoType.FAULT_EVENT) { } else if (responseMessageBlock.getType() == MessageBlockType.POD_INFO_RESPONSE && ((PodInfoResponse) responseMessageBlock).getSubType() == PodInfoType.FAULT_EVENT) {
PodInfoFaultEvent faultEvent = ((PodInfoResponse) responseMessageBlock).getPodInfo(); PodInfoFaultEvent faultEvent = ((PodInfoResponse) responseMessageBlock).getPodInfo();
podState.setFaultEvent(faultEvent); podStateManager.setFaultEvent(faultEvent);
podStateManager.setLastFailedCommunication(DateTime.now());
throw new PodFaultException(faultEvent); throw new PodFaultException(faultEvent);
} else { } else {
podStateManager.setLastFailedCommunication(DateTime.now());
throw new IllegalResponseException(responseClass.getSimpleName(), responseMessageBlock.getType()); throw new IllegalResponseException(responseClass.getSimpleName(), responseMessageBlock.getType());
} }
} }
} }
podStateManager.setLastFailedCommunication(DateTime.now());
throw new NonceResyncException(); throw new NonceResyncException();
} }
private MessageBlock transportMessages(PodState podState, OmnipodMessage message, Integer addressOverride, Integer ackAddressOverride) { private MessageBlock transportMessages(PodStateManager podStateManager, OmnipodMessage message, Integer addressOverride, Integer ackAddressOverride) {
int packetAddress = podState.getAddress(); int packetAddress = podStateManager.getAddress();
if (addressOverride != null) { if (addressOverride != null) {
packetAddress = addressOverride; packetAddress = addressOverride;
} }
podState.increaseMessageNumber(); podStateManager.increaseMessageNumber();
boolean firstPacket = true; boolean firstPacket = true;
byte[] encodedMessage; byte[] encodedMessage;
@ -203,7 +208,7 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager {
OmnipodPacket response = null; OmnipodPacket response = null;
while (encodedMessage.length > 0) { while (encodedMessage.length > 0) {
PacketType packetType = firstPacket ? PacketType.PDM : PacketType.CON; 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(); byte[] encodedMessageInPacket = packet.getEncodedMessage();
// getting the data remaining to be sent // getting the data remaining to be sent
@ -212,7 +217,7 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager {
try { try {
// We actually ignore previous (ack) responses if it was not last packet to send // 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) { } catch (Exception ex) {
OmnipodException newException; OmnipodException newException;
if (ex instanceof OmnipodException) { if (ex instanceof OmnipodException) {
@ -245,15 +250,15 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager {
if (receivedMessage.getAddress() != message.getAddress()) { if (receivedMessage.getAddress() != message.getAddress()) {
throw new IllegalMessageAddressException(message.getAddress(), receivedMessage.getAddress()); throw new IllegalMessageAddressException(message.getAddress(), receivedMessage.getAddress());
} }
if (receivedMessage.getSequenceNumber() != podState.getMessageNumber()) { if (receivedMessage.getSequenceNumber() != podStateManager.getMessageNumber()) {
throw new IllegalMessageSequenceNumberException(podState.getMessageNumber(), receivedMessage.getSequenceNumber()); throw new IllegalMessageSequenceNumberException(podStateManager.getMessageNumber(), receivedMessage.getSequenceNumber());
} }
} catch (NotEnoughDataException ex) { } catch (NotEnoughDataException ex) {
// Message is (probably) not complete yet // Message is (probably) not complete yet
OmnipodPacket ackForCon = createAckPacket(podState, packetAddress, ackAddressOverride); OmnipodPacket ackForCon = createAckPacket(podStateManager, packetAddress, ackAddressOverride);
try { try {
OmnipodPacket conPacket = exchangePackets(podState, ackForCon, 3, 40); OmnipodPacket conPacket = exchangePackets(podStateManager, ackForCon, 3, 40);
if (conPacket.getPacketType() != PacketType.CON) { if (conPacket.getPacketType() != PacketType.CON) {
throw new IllegalPacketTypeException(PacketType.CON, conPacket.getPacketType()); throw new IllegalPacketTypeException(PacketType.CON, conPacket.getPacketType());
} }
@ -267,7 +272,7 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager {
} }
} }
ackUntilQuiet(podState, packetAddress, ackAddressOverride); ackUntilQuiet(podStateManager, packetAddress, ackAddressOverride);
List<MessageBlock> messageBlocks = receivedMessage.getMessageBlocks(); List<MessageBlock> messageBlocks = receivedMessage.getMessageBlocks();
@ -281,24 +286,24 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager {
MessageBlock messageBlock = messageBlocks.get(0); MessageBlock messageBlock = messageBlocks.get(0);
if (messageBlock.getType() != MessageBlockType.ERROR_RESPONSE) { if (messageBlock.getType() != MessageBlockType.ERROR_RESPONSE) {
podState.increaseMessageNumber(); podStateManager.increaseMessageNumber();
} }
return messageBlock; return messageBlock;
} }
private OmnipodPacket createAckPacket(PodState podState, Integer packetAddress, Integer messageAddress) { private OmnipodPacket createAckPacket(PodStateManager podStateManager, Integer packetAddress, Integer messageAddress) {
if (packetAddress == null) { if (packetAddress == null) {
packetAddress = podState.getAddress(); packetAddress = podStateManager.getAddress();
} }
if (messageAddress == null) { 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) { private void ackUntilQuiet(PodStateManager podStateManager, Integer packetAddress, Integer messageAddress) {
OmnipodPacket ack = createAckPacket(podState, packetAddress, messageAddress); OmnipodPacket ack = createAckPacket(podStateManager, packetAddress, messageAddress);
boolean quiet = false; boolean quiet = false;
while (!quiet) try { while (!quiet) try {
sendAndListen(ack, 300, 1, 0, 40, OmnipodPacket.class); sendAndListen(ack, 300, 1, 0, 40, OmnipodPacket.class);
@ -314,21 +319,21 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager {
throw new CommunicationException(CommunicationException.Type.UNEXPECTED_EXCEPTION, ex); throw new CommunicationException(CommunicationException.Type.UNEXPECTED_EXCEPTION, ex);
} }
podState.increasePacketNumber(); podStateManager.increasePacketNumber();
} }
private OmnipodPacket exchangePackets(PodState podState, OmnipodPacket packet) { private OmnipodPacket exchangePackets(PodStateManager podStateManager, OmnipodPacket packet) {
return exchangePackets(podState, packet, 0, 333, 9000, 127); return exchangePackets(podStateManager, packet, 0, 333, 9000, 127);
} }
private OmnipodPacket exchangePackets(PodState podState, OmnipodPacket packet, int repeatCount, int preambleExtensionMilliseconds) { private OmnipodPacket exchangePackets(PodStateManager podStateManager, OmnipodPacket packet, int repeatCount, int preambleExtensionMilliseconds) {
return exchangePackets(podState, packet, repeatCount, 333, 9000, 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; long timeoutTime = System.currentTimeMillis() + exchangeTimeoutMilliseconds;
podState.increasePacketNumber(); podStateManager.increasePacketNumber();
while (System.currentTimeMillis() < timeoutTime) { while (System.currentTimeMillis() < timeoutTime) {
OmnipodPacket response = null; OmnipodPacket response = null;
@ -353,13 +358,13 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager {
continue; continue;
} }
if (response.getSequenceNumber() != podState.getPacketNumber()) { if (response.getSequenceNumber() != podStateManager.getPacketNumber()) {
aapsLogger.debug(LTag.PUMPBTCOMM, "Packet sequence number " + response.getSequenceNumber() + " does not match " + podState.getPacketNumber()); aapsLogger.debug(LTag.PUMPBTCOMM, "Packet sequence number " + response.getSequenceNumber() + " does not match " + podStateManager.getPacketNumber());
continue; continue;
} }
// Once we have verification that the POD heard us, we can increment our counters // Once we have verification that the POD heard us, we can increment our counters
podState.increasePacketNumber(); podStateManager.increasePacketNumber();
return response; return response;
} }

View file

@ -5,7 +5,6 @@ import org.joda.time.DateTimeZone;
import org.joda.time.Duration; import org.joda.time.Duration;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.Random;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.concurrent.TimeUnit; 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.PodInfoType;
import info.nightscout.androidaps.plugins.pump.omnipod.defs.SetupProgress; 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.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.defs.state.PodStateChangedHandler;
import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException; import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException;
import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst;
import info.nightscout.androidaps.utils.sharedPreferences.SP; import info.nightscout.androidaps.utils.sharedPreferences.SP;
@ -55,49 +53,45 @@ import io.reactivex.subjects.SingleSubject;
public class OmnipodManager { public class OmnipodManager {
private static final int ACTION_VERIFICATION_TRIES = 3; private static final int ACTION_VERIFICATION_TRIES = 3;
protected final OmnipodCommunicationManager communicationService; private final OmnipodCommunicationManager communicationService;
private final PodStateChangedHandler podStateChangedHandler; private PodStateManager podStateManager;
protected PodSessionState podState;
private ActiveBolusData activeBolusData; private ActiveBolusData activeBolusData;
private final Object bolusDataMutex = new Object(); private final Object bolusDataMutex = new Object();
private AAPSLogger aapsLogger; private AAPSLogger aapsLogger;
private SP sp;
public OmnipodManager(AAPSLogger aapsLogger, public OmnipodManager(AAPSLogger aapsLogger,
SP sp, SP sp,
OmnipodCommunicationManager communicationService, OmnipodCommunicationManager communicationService,
PodSessionState podState, PodStateManager podStateManager) {
PodStateChangedHandler podStateChangedHandler) {
if (communicationService == null) { if (communicationService == null) {
throw new IllegalArgumentException("Communication service cannot be null"); throw new IllegalArgumentException("Communication service cannot be null");
} }
this.aapsLogger = aapsLogger; if (podStateManager == null) {
this.sp = sp; throw new IllegalArgumentException("Pod State Manager can not be null");
this.communicationService = communicationService;
if (podState != null) {
podState.setStateChangedHandler(podStateChangedHandler);
} }
this.podState = podState; this.aapsLogger = aapsLogger;
this.podStateChangedHandler = podStateChangedHandler; this.communicationService = communicationService;
this.podStateManager = podStateManager;
} }
public synchronized Single<SetupActionResult> pairAndPrime(int address) { public synchronized Single<SetupActionResult> pairAndPrime() {
logStartingCommandExecution("pairAndPrime"); logStartingCommandExecution("pairAndPrime");
try { try {
if (podState == null || podState.getSetupProgress().isBefore(SetupProgress.POD_CONFIGURED)) { if (!podStateManager.hasState() || !podStateManager.isPaired() || podStateManager.getSetupProgress().isBefore(SetupProgress.POD_CONFIGURED)) {
// Always send both 0x07 and 0x03 on retries // Always send both 0x07 and 0x03 on retries
podState = communicationService.executeAction( communicationService.executeAction(
new AssignAddressAction(podStateChangedHandler, address)); new AssignAddressAction(podStateManager));
communicationService.executeAction(new SetupPodAction(podState)); communicationService.executeAction(new SetupPodAction(podStateManager));
} else if (SetupProgress.PRIMING.isBefore(podState.getSetupProgress())) { } else if (SetupProgress.PRIMING.isBefore(podStateManager.getSetupProgress())) {
throw new IllegalSetupProgressException(SetupProgress.POD_CONFIGURED, podState.getSetupProgress()); throw new IllegalSetupProgressException(SetupProgress.POD_CONFIGURED, podStateManager.getSetupProgress());
} }
communicationService.executeAction(new PrimeAction(new PrimeService(), podState)); communicationService.executeAction(new PrimeAction(new PrimeService(), podStateManager));
} finally { } finally {
logCommandExecutionFinished("pairAndPrime"); logCommandExecutionFinished("pairAndPrime");
} }
@ -106,21 +100,21 @@ public class OmnipodManager {
return Single.timer(delayInSeconds, TimeUnit.SECONDS) // return Single.timer(delayInSeconds, TimeUnit.SECONDS) //
.map(o -> verifySetupAction(statusResponse -> .map(o -> verifySetupAction(statusResponse ->
PrimeAction.updatePrimingStatus(podState, statusResponse, aapsLogger), SetupProgress.PRIMING_FINISHED)) // PrimeAction.updatePrimingStatus(podStateManager, statusResponse, aapsLogger), SetupProgress.PRIMING_FINISHED)) //
.observeOn(Schedulers.io()); .observeOn(Schedulers.io());
} }
public synchronized Single<SetupActionResult> insertCannula(BasalSchedule basalSchedule) { public synchronized Single<SetupActionResult> insertCannula(BasalSchedule basalSchedule) {
if (podState == null || podState.getSetupProgress().isBefore(SetupProgress.PRIMING_FINISHED)) { if (!podStateManager.hasState() || !podStateManager.isPaired() || podStateManager.getSetupProgress().isBefore(SetupProgress.PRIMING_FINISHED)) {
throw new IllegalSetupProgressException(SetupProgress.PRIMING_FINISHED, podState == null ? null : podState.getSetupProgress()); throw new IllegalSetupProgressException(SetupProgress.PRIMING_FINISHED, !podStateManager.hasState() ? null : podStateManager.getSetupProgress());
} else if (podState.getSetupProgress().isAfter(SetupProgress.CANNULA_INSERTING)) { } else if (podStateManager.getSetupProgress().isAfter(SetupProgress.CANNULA_INSERTING)) {
throw new IllegalSetupProgressException(SetupProgress.CANNULA_INSERTING, podState.getSetupProgress()); throw new IllegalSetupProgressException(SetupProgress.CANNULA_INSERTING, podStateManager.getSetupProgress());
} }
logStartingCommandExecution("insertCannula [basalSchedule=" + basalSchedule + "]"); logStartingCommandExecution("insertCannula [basalSchedule=" + basalSchedule + "]");
try { try {
communicationService.executeAction(new InsertCannulaAction(new InsertCannulaService(), podState, basalSchedule)); communicationService.executeAction(new InsertCannulaAction(new InsertCannulaService(), podStateManager, basalSchedule));
} finally { } finally {
logCommandExecutionFinished("insertCannula"); logCommandExecutionFinished("insertCannula");
} }
@ -129,19 +123,19 @@ public class OmnipodManager {
return Single.timer(delayInSeconds, TimeUnit.SECONDS) // return Single.timer(delayInSeconds, TimeUnit.SECONDS) //
.map(o -> verifySetupAction(statusResponse -> .map(o -> verifySetupAction(statusResponse ->
InsertCannulaAction.updateCannulaInsertionStatus(podState, statusResponse, aapsLogger), SetupProgress.COMPLETED)) // InsertCannulaAction.updateCannulaInsertionStatus(podStateManager, statusResponse, aapsLogger), SetupProgress.COMPLETED)) //
.observeOn(Schedulers.io()); .observeOn(Schedulers.io());
} }
public synchronized StatusResponse getPodStatus() { public synchronized StatusResponse getPodStatus() {
if (podState == null) { if (!podStateManager.hasState()) {
throw new IllegalSetupProgressException(SetupProgress.PRIMING_FINISHED, null); throw new IllegalSetupProgressException(SetupProgress.PRIMING_FINISHED, null);
} }
logStartingCommandExecution("getPodStatus"); logStartingCommandExecution("getPodStatus");
try { try {
return communicationService.executeAction(new GetStatusAction(podState)); return communicationService.executeAction(new GetStatusAction(podStateManager));
} finally { } finally {
logCommandExecutionFinished("getPodStatus"); logCommandExecutionFinished("getPodStatus");
} }
@ -153,7 +147,7 @@ public class OmnipodManager {
logStartingCommandExecution("getPodInfo"); logStartingCommandExecution("getPodInfo");
try { try {
return communicationService.executeAction(new GetPodInfoAction(podState, podInfoType)); return communicationService.executeAction(new GetPodInfoAction(podStateManager, podInfoType));
} finally { } finally {
logCommandExecutionFinished("getPodInfo"); logCommandExecutionFinished("getPodInfo");
} }
@ -165,7 +159,7 @@ public class OmnipodManager {
logStartingCommandExecution("acknowledgeAlerts"); logStartingCommandExecution("acknowledgeAlerts");
try { try {
return executeAndVerify(() -> communicationService.executeAction(new AcknowledgeAlertsAction(podState, podState.getActiveAlerts()))); return executeAndVerify(() -> communicationService.executeAction(new AcknowledgeAlertsAction(podStateManager, podStateManager.getActiveAlerts())));
} finally { } finally {
logCommandExecutionFinished("acknowledgeAlerts"); logCommandExecutionFinished("acknowledgeAlerts");
} }
@ -187,8 +181,8 @@ public class OmnipodManager {
try { try {
try { try {
return executeAndVerify(() -> communicationService.executeAction(new SetBasalScheduleAction(podState, schedule, return executeAndVerify(() -> communicationService.executeAction(new SetBasalScheduleAction(podStateManager, schedule,
false, podState.getScheduleOffset(), acknowledgementBeep))); false, podStateManager.getScheduleOffset(), acknowledgementBeep)));
} catch (OmnipodException ex) { } catch (OmnipodException ex) {
// Treat all exceptions as uncertain failures, because all delivery has been suspended here. // 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 // Setting this to an uncertain failure will enable for the user to get an appropriate warning
@ -214,9 +208,10 @@ public class OmnipodManager {
} }
try { try {
return executeAndVerify(() -> communicationService.executeAction(new SetTempBasalAction( StatusResponse statusResponse = executeAndVerify(() -> communicationService.executeAction(new SetTempBasalAction(
podState, rate, duration, podStateManager, rate, duration,
acknowledgementBeep, completionBeep))); acknowledgementBeep, completionBeep)));
return statusResponse;
} catch (OmnipodException ex) { } catch (OmnipodException ex) {
// Treat all exceptions as uncertain failures, because all delivery has been suspended here. // 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 // Setting this to an uncertain failure will enable for the user to get an appropriate warning
@ -238,7 +233,7 @@ public class OmnipodManager {
try { try {
return executeAndVerify(() -> { 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()); aapsLogger.info(LTag.PUMPBTCOMM, "Status response after cancel delivery[types={}]: {}", deliveryTypes.toString(), statusResponse.toString());
return statusResponse; return statusResponse;
}); });
@ -258,7 +253,7 @@ public class OmnipodManager {
CommandDeliveryStatus commandDeliveryStatus = CommandDeliveryStatus.SUCCESS; CommandDeliveryStatus commandDeliveryStatus = CommandDeliveryStatus.SUCCESS;
try { try {
executeAndVerify(() -> communicationService.executeAction(new BolusAction(podState, units, acknowledgementBeep, completionBeep))); executeAndVerify(() -> communicationService.executeAction(new BolusAction(podStateManager, units, acknowledgementBeep, completionBeep)));
} catch (OmnipodException ex) { } catch (OmnipodException ex) {
if (ex.isCertainFailure()) { if (ex.isCertainFailure()) {
throw ex; throw ex;
@ -272,6 +267,7 @@ public class OmnipodManager {
} }
DateTime startDate = DateTime.now().minus(OmnipodConst.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION); DateTime startDate = DateTime.now().minus(OmnipodConst.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION);
podStateManager.setLastBolus(startDate, units);
CompositeDisposable disposables = new CompositeDisposable(); CompositeDisposable disposables = new CompositeDisposable();
Duration bolusDuration = calculateBolusDuration(units, OmnipodConst.POD_BOLUS_DELIVERY_RATE); Duration bolusDuration = calculateBolusDuration(units, OmnipodConst.POD_BOLUS_DELIVERY_RATE);
@ -339,7 +335,7 @@ public class OmnipodManager {
synchronized (bolusDataMutex) { synchronized (bolusDataMutex) {
if (activeBolusData == null) { 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 + "]"); logStartingCommandExecution("cancelBolus [acknowledgementBeep=" + acknowledgementBeep + "]");
@ -358,8 +354,10 @@ public class OmnipodManager {
private void discardActiveBolusData(double unitsNotDelivered) { private void discardActiveBolusData(double unitsNotDelivered) {
synchronized (bolusDataMutex) { synchronized (bolusDataMutex) {
double unitsDelivered = activeBolusData.getUnits() - unitsNotDelivered;
podStateManager.setLastBolus(activeBolusData.getStartDate(), unitsDelivered);
activeBolusData.getDisposables().dispose(); activeBolusData.getDisposables().dispose();
activeBolusData.getBolusCompletionSubject().onSuccess(new BolusDeliveryResult(activeBolusData.getUnits() - unitsNotDelivered)); activeBolusData.getBolusCompletionSubject().onSuccess(new BolusDeliveryResult(unitsDelivered));
activeBolusData = null; activeBolusData = null;
} }
} }
@ -374,8 +372,8 @@ public class OmnipodManager {
logStartingCommandExecution("resumeDelivery"); logStartingCommandExecution("resumeDelivery");
try { try {
return executeAndVerify(() -> communicationService.executeAction(new SetBasalScheduleAction(podState, podState.getBasalSchedule(), return executeAndVerify(() -> communicationService.executeAction(new SetBasalScheduleAction(podStateManager, podStateManager.getBasalSchedule(),
false, podState.getScheduleOffset(), acknowledgementBeep))); false, podStateManager.getScheduleOffset(), acknowledgementBeep)));
} finally { } finally {
logCommandExecutionFinished("resumeDelivery"); logCommandExecutionFinished("resumeDelivery");
} }
@ -395,18 +393,18 @@ public class OmnipodManager {
throw ex; throw ex;
} }
DateTimeZone oldTimeZone = podState.getTimeZone(); DateTimeZone oldTimeZone = podStateManager.getTimeZone();
try { try {
// Joda seems to cache the default time zone, so we use the JVM's // Joda seems to cache the default time zone, so we use the JVM's
DateTimeZone.setDefault(DateTimeZone.forTimeZone(TimeZone.getDefault())); 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) { } catch (OmnipodException ex) {
// Treat all exceptions as uncertain failures, because all delivery has been suspended here. // 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 // 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); ex.setCertainFailure(false);
throw ex; throw ex;
} finally { } finally {
@ -415,7 +413,7 @@ public class OmnipodManager {
} }
public synchronized void deactivatePod() { public synchronized void deactivatePod() {
if (podState == null) { if (!podStateManager.isPaired()) {
throw new IllegalSetupProgressException(SetupProgress.ADDRESS_ASSIGNED, null); throw new IllegalSetupProgressException(SetupProgress.ADDRESS_ASSIGNED, null);
} }
@ -424,7 +422,7 @@ public class OmnipodManager {
// Try to get pulse log for diagnostics // Try to get pulse log for diagnostics
// FIXME replace by storing to file // FIXME replace by storing to file
try { 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(); PodInfoRecentPulseLog pulseLogInfo = podInfoResponse.getPodInfo();
aapsLogger.info(LTag.PUMPBTCOMM, "Retrieved pulse log from the pod: {}", pulseLogInfo.toString()); aapsLogger.info(LTag.PUMPBTCOMM, "Retrieved pulse log from the pod: {}", pulseLogInfo.toString());
} catch (Exception ex) { } catch (Exception ex) {
@ -433,20 +431,14 @@ public class OmnipodManager {
try { try {
// Always send acknowledgement beeps here. Matches the PDM's behavior // 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) { } catch (PodFaultException ex) {
aapsLogger.info(LTag.PUMPBTCOMM, "Ignoring PodFaultException in deactivatePod", ex); aapsLogger.info(LTag.PUMPBTCOMM, "Ignoring PodFaultException in deactivatePod", ex);
} finally { } finally {
logCommandExecutionFinished("deactivatePod"); logCommandExecutionFinished("deactivatePod");
} }
resetPodState(false); podStateManager.removeState();
}
public void resetPodState(boolean forcedByUser) {
aapsLogger.warn(LTag.PUMPBTCOMM, "resetPodState has been called. forcedByUser={}", forcedByUser);
podState = null;
sp.remove(OmnipodConst.Prefs.PodState);
} }
public OmnipodCommunicationManager getCommunicationService() { public OmnipodCommunicationManager getCommunicationService() {
@ -454,11 +446,11 @@ public class OmnipodManager {
} }
public DateTime getTime() { public DateTime getTime() {
return podState.getTime(); return podStateManager.getTime();
} }
public boolean isReadyForDelivery() { public boolean isReadyForDelivery() {
return podState != null && podState.getSetupProgress() == SetupProgress.COMPLETED; return podStateManager.isSetupCompleted();
} }
public boolean hasActiveBolus() { public boolean hasActiveBolus() {
@ -467,15 +459,6 @@ public class OmnipodManager {
} }
} }
// FIXME this is dirty, we should not expose the original pod state
public PodSessionState getPodState() {
return this.podState;
}
public String getPodStateAsString() {
return podState == null ? "null" : podState.toString();
}
// Only works for commands with nonce resyncable message blocks // Only works for commands with nonce resyncable message blocks
// FIXME method is too big, needs refactoring // FIXME method is too big, needs refactoring
private StatusResponse executeAndVerify(VerifiableAction runnable) { private StatusResponse executeAndVerify(VerifiableAction runnable) {
@ -489,8 +472,8 @@ public class OmnipodManager {
try { try {
logStartingCommandExecution("verifyCommand"); logStartingCommandExecution("verifyCommand");
StatusResponse statusResponse = communicationService.sendCommand(StatusResponse.class, podState, StatusResponse statusResponse = communicationService.sendCommand(StatusResponse.class, podStateManager,
new CancelDeliveryCommand(podState.getCurrentNonce(), BeepType.NO_BEEP, DeliveryType.NONE), false); 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); aapsLogger.info(LTag.PUMPBTCOMM, "Command status resolved to SUCCESS. Status response after cancelDelivery[types=DeliveryType.NONE]: {}", statusResponse);
return statusResponse; return statusResponse;
@ -517,7 +500,7 @@ public class OmnipodManager {
private void assertReadyForDelivery() { private void assertReadyForDelivery() {
if (!isReadyForDelivery()) { if (!isReadyForDelivery()) {
throw new IllegalSetupProgressException(SetupProgress.COMPLETED, podState == null ? null : podState.getSetupProgress()); throw new IllegalSetupProgressException(SetupProgress.COMPLETED, !podStateManager.hasState() ? null : podStateManager.getSetupProgress());
} }
} }
@ -525,15 +508,15 @@ public class OmnipodManager {
SetupActionResult result = null; SetupActionResult result = null;
for (int i = 0; ACTION_VERIFICATION_TRIES > i; i++) { for (int i = 0; ACTION_VERIFICATION_TRIES > i; i++) {
try { try {
StatusResponse delayedStatusResponse = communicationService.executeAction(new GetStatusAction(podState)); StatusResponse delayedStatusResponse = communicationService.executeAction(new GetStatusAction(podStateManager));
setupActionResponseHandler.accept(delayedStatusResponse); setupActionResponseHandler.accept(delayedStatusResponse);
if (podState.getSetupProgress().equals(expectedSetupProgress)) { if (podStateManager.getSetupProgress().equals(expectedSetupProgress)) {
result = new SetupActionResult(SetupActionResult.ResultType.SUCCESS); result = new SetupActionResult(SetupActionResult.ResultType.SUCCESS);
break; break;
} else { } else {
result = new SetupActionResult(SetupActionResult.ResultType.FAILURE) // result = new SetupActionResult(SetupActionResult.ResultType.FAILURE) //
.setupProgress(podState.getSetupProgress()); .setupProgress(podStateManager.getSetupProgress());
break; break;
} }
} catch (Exception ex) { } catch (Exception ex) {
@ -564,15 +547,6 @@ public class OmnipodManager {
return ex instanceof OmnipodException && ((OmnipodException) ex).isCertainFailure(); 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 { public static class BolusCommandResult {
private final CommandDeliveryStatus commandDeliveryStatus; private final CommandDeliveryStatus commandDeliveryStatus;
private final SingleSubject<BolusDeliveryResult> deliveryResultSubject; private final SingleSubject<BolusDeliveryResult> deliveryResultSubject;

View file

@ -3,37 +3,37 @@ package info.nightscout.androidaps.plugins.pump.omnipod.comm.action;
import java.util.Collections; import java.util.Collections;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; 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.command.AcknowledgeAlertsCommand;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; 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.AlertSet;
import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSlot; 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.defs.state.PodStateManager;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException;
public class AcknowledgeAlertsAction implements OmnipodAction<StatusResponse> { public class AcknowledgeAlertsAction implements OmnipodAction<StatusResponse> {
private final PodSessionState podState; private final PodStateManager podStateManager;
private final AlertSet alerts; private final AlertSet alerts;
public AcknowledgeAlertsAction(PodSessionState podState, AlertSet alerts) { public AcknowledgeAlertsAction(PodStateManager podStateManager, AlertSet alerts) {
if (podState == null) { if (podStateManager == null) {
throw new ActionInitializationException("Pod state cannot be null"); throw new ActionInitializationException("Pod state manager cannot be null");
} }
if (alerts == null) { if (alerts == null) {
throw new ActionInitializationException("Alert set can not be null"); throw new ActionInitializationException("Alert set can not be null");
} else if (alerts.size() == 0) { } else if (alerts.size() == 0) {
throw new ActionInitializationException("Alert set can not be empty"); throw new ActionInitializationException("Alert set can not be empty");
} }
this.podState = podState; this.podStateManager = podStateManager;
this.alerts = alerts; this.alerts = alerts;
} }
public AcknowledgeAlertsAction(PodSessionState podState, AlertSlot alertSlot) { public AcknowledgeAlertsAction(PodStateManager podStateManager, AlertSlot alertSlot) {
this(podState, new AlertSet(Collections.singletonList(alertSlot))); this(podStateManager, new AlertSet(Collections.singletonList(alertSlot)));
} }
@Override @Override
public StatusResponse execute(OmnipodCommunicationManager communicationService) { public StatusResponse execute(OmnipodCommunicationManager communicationService) {
return communicationService.sendCommand(StatusResponse.class, podState, return communicationService.sendCommand(StatusResponse.class, podStateManager,
new AcknowledgeAlertsCommand(podState.getCurrentNonce(), alerts)); new AcknowledgeAlertsCommand(podStateManager.getCurrentNonce(), alerts));
} }
} }

View file

@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.pump.omnipod.comm.action;
import org.joda.time.DateTimeZone; import org.joda.time.DateTimeZone;
import java.util.Collections; 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.OmnipodCommunicationManager;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalMessageAddressException; import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalMessageAddressException;
@ -10,45 +11,51 @@ 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.OmnipodMessage;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.AssignAddressCommand; 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.comm.message.response.VersionResponse;
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.defs.state.PodSetupState;
import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateChangedHandler;
import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst;
public class AssignAddressAction implements OmnipodAction<PodSessionState> { public class AssignAddressAction implements OmnipodAction<VersionResponse> {
private final int address; private final PodStateManager podStateManager;
private final PodStateChangedHandler podStateChangedHandler;
public AssignAddressAction(PodStateChangedHandler podStateChangedHandler, int address) { public AssignAddressAction(PodStateManager podStateManager) {
this.address = address; if (podStateManager == null) {
this.podStateChangedHandler = podStateChangedHandler; throw new IllegalArgumentException("podStateManager can not be null");
}
this.podStateManager = podStateManager;
} }
@Override @Override
public PodSessionState execute(OmnipodCommunicationManager communicationService) { public VersionResponse execute(OmnipodCommunicationManager communicationService) {
PodSetupState setupState = new PodSetupState(address, 0x00, 0x00); 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, 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, VersionResponse assignAddressResponse = communicationService.exchangeMessages(VersionResponse.class, podStateManager, assignAddressMessage,
OmnipodConst.DEFAULT_ADDRESS, setupState.getAddress()); OmnipodConst.DEFAULT_ADDRESS, podStateManager.getAddress());
if (!assignAddressResponse.isAssignAddressVersionResponse()) { if (!assignAddressResponse.isAssignAddressVersionResponse()) {
throw new IllegalVersionResponseTypeException("assignAddress", "setupPod"); throw new IllegalVersionResponseTypeException("assignAddress", "setupPod");
} }
if (assignAddressResponse.getAddress() != address) { if (assignAddressResponse.getAddress() != podStateManager.getAddress()) {
throw new IllegalMessageAddressException(address, assignAddressResponse.getAddress()); throw new IllegalMessageAddressException(podStateManager.getAddress(), assignAddressResponse.getAddress());
} }
DateTimeZone timeZone = DateTimeZone.getDefault(); podStateManager.setPairingParameters(assignAddressResponse.getLot(), assignAddressResponse.getTid(), //
assignAddressResponse.getPiVersion(), assignAddressResponse.getPmVersion(), DateTimeZone.getDefault());
PodSessionState podState = new PodSessionState(timeZone, address, assignAddressResponse.getPiVersion(), return assignAddressResponse;
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
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);
} }
} }

View file

@ -5,49 +5,49 @@ import org.joda.time.Duration;
import java.util.Arrays; import java.util.Arrays;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; 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.OmnipodMessage;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.BolusExtraCommand; 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.command.SetInsulinScheduleCommand;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; 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.schedule.BolusDeliverySchedule;
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.comm.exception.ActionInitializationException;
public class BolusAction implements OmnipodAction<StatusResponse> { public class BolusAction implements OmnipodAction<StatusResponse> {
private final PodSessionState podState; private final PodStateManager podStateManager;
private final double units; private final double units;
private final Duration timeBetweenPulses; private final Duration timeBetweenPulses;
private final boolean acknowledgementBeep; private final boolean acknowledgementBeep;
private final boolean completionBeep; private final boolean completionBeep;
public BolusAction(PodSessionState podState, double units, Duration timeBetweenPulses, public BolusAction(PodStateManager podStateManager, double units, Duration timeBetweenPulses,
boolean acknowledgementBeep, boolean completionBeep) { boolean acknowledgementBeep, boolean completionBeep) {
if (podState == null) { if (podStateManager == null) {
throw new ActionInitializationException("Pod state cannot be null"); throw new ActionInitializationException("Pod state manager cannot be null");
} }
if (timeBetweenPulses == null) { if (timeBetweenPulses == null) {
throw new ActionInitializationException("Time between pulses cannot be null"); throw new ActionInitializationException("Time between pulses cannot be null");
} }
this.podState = podState; this.podStateManager = podStateManager;
this.units = units; this.units = units;
this.timeBetweenPulses = timeBetweenPulses; this.timeBetweenPulses = timeBetweenPulses;
this.acknowledgementBeep = acknowledgementBeep; this.acknowledgementBeep = acknowledgementBeep;
this.completionBeep = completionBeep; this.completionBeep = completionBeep;
} }
public BolusAction(PodSessionState podState, double units, boolean acknowledgementBeep, boolean completionBeep) { public BolusAction(PodStateManager podStateManager, double units, boolean acknowledgementBeep, boolean completionBeep) {
this(podState, units, Duration.standardSeconds(2), acknowledgementBeep, completionBeep); this(podStateManager, units, Duration.standardSeconds(2), acknowledgementBeep, completionBeep);
} }
@Override @Override
public StatusResponse execute(OmnipodCommunicationManager communicationService) { public StatusResponse execute(OmnipodCommunicationManager communicationService) {
BolusDeliverySchedule bolusDeliverySchedule = new BolusDeliverySchedule(units, timeBetweenPulses); BolusDeliverySchedule bolusDeliverySchedule = new BolusDeliverySchedule(units, timeBetweenPulses);
SetInsulinScheduleCommand setInsulinScheduleCommand = new SetInsulinScheduleCommand( SetInsulinScheduleCommand setInsulinScheduleCommand = new SetInsulinScheduleCommand(
podState.getCurrentNonce(), bolusDeliverySchedule); podStateManager.getCurrentNonce(), bolusDeliverySchedule);
BolusExtraCommand bolusExtraCommand = new BolusExtraCommand(units, timeBetweenPulses, BolusExtraCommand bolusExtraCommand = new BolusExtraCommand(units, timeBetweenPulses,
acknowledgementBeep, completionBeep); acknowledgementBeep, completionBeep);
OmnipodMessage primeBolusMessage = new OmnipodMessage(podState.getAddress(), OmnipodMessage primeBolusMessage = new OmnipodMessage(podStateManager.getAddress(),
Arrays.asList(setInsulinScheduleCommand, bolusExtraCommand), podState.getMessageNumber()); Arrays.asList(setInsulinScheduleCommand, bolusExtraCommand), podStateManager.getMessageNumber());
return communicationService.exchangeMessages(StatusResponse.class, podState, primeBolusMessage); return communicationService.exchangeMessages(StatusResponse.class, podStateManager, primeBolusMessage);
} }
} }

View file

@ -5,29 +5,29 @@ import java.util.EnumSet;
import java.util.List; import java.util.List;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; 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.MessageBlock;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.OmnipodMessage; 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.command.CancelDeliveryCommand;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; 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.BeepType;
import info.nightscout.androidaps.plugins.pump.omnipod.defs.DeliveryType; 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.defs.state.PodStateManager;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException;
public class CancelDeliveryAction implements OmnipodAction<StatusResponse> { public class CancelDeliveryAction implements OmnipodAction<StatusResponse> {
private final PodSessionState podState; private final PodStateManager podStateManager;
private final EnumSet<DeliveryType> deliveryTypes; private final EnumSet<DeliveryType> deliveryTypes;
private final boolean acknowledgementBeep; private final boolean acknowledgementBeep;
public CancelDeliveryAction(PodSessionState podState, EnumSet<DeliveryType> deliveryTypes, public CancelDeliveryAction(PodStateManager podStateManager, EnumSet<DeliveryType> deliveryTypes,
boolean acknowledgementBeep) { boolean acknowledgementBeep) {
if (podState == null) { if (podStateManager == null) {
throw new ActionInitializationException("Pod state cannot be null"); throw new ActionInitializationException("Pod state manager cannot be null");
} }
if (deliveryTypes == null) { if (deliveryTypes == null) {
throw new ActionInitializationException("Delivery types cannot be null"); throw new ActionInitializationException("Delivery types cannot be null");
} }
this.podState = podState; this.podStateManager = podStateManager;
this.deliveryTypes = deliveryTypes; this.deliveryTypes = deliveryTypes;
this.acknowledgementBeep = acknowledgementBeep; this.acknowledgementBeep = acknowledgementBeep;
} }
@ -43,14 +43,18 @@ public class CancelDeliveryAction implements OmnipodAction<StatusResponse> {
EnumSet<DeliveryType> deliveryTypeWithBeep = EnumSet.of(deliveryTypeList.remove(deliveryTypeList.size() - 1)); EnumSet<DeliveryType> deliveryTypeWithBeep = EnumSet.of(deliveryTypeList.remove(deliveryTypeList.size() - 1));
EnumSet<DeliveryType> deliveryTypesWithoutBeep = EnumSet.copyOf(deliveryTypeList); EnumSet<DeliveryType> deliveryTypesWithoutBeep = EnumSet.copyOf(deliveryTypeList);
messageBlocks.add(new CancelDeliveryCommand(podState.getCurrentNonce(), BeepType.NO_BEEP, deliveryTypesWithoutBeep)); messageBlocks.add(new CancelDeliveryCommand(podStateManager.getCurrentNonce(), BeepType.NO_BEEP, deliveryTypesWithoutBeep));
messageBlocks.add(new CancelDeliveryCommand(podState.getCurrentNonce(), BeepType.BEEP, deliveryTypeWithBeep)); messageBlocks.add(new CancelDeliveryCommand(podStateManager.getCurrentNonce(), BeepType.BEEP, deliveryTypeWithBeep));
} else { } else {
messageBlocks.add(new CancelDeliveryCommand(podState.getCurrentNonce(), messageBlocks.add(new CancelDeliveryCommand(podStateManager.getCurrentNonce(),
acknowledgementBeep && deliveryTypes.size() == 1 ? BeepType.BEEP : BeepType.NO_BEEP, deliveryTypes)); acknowledgementBeep && deliveryTypes.size() == 1 ? BeepType.BEEP : BeepType.NO_BEEP, deliveryTypes));
} }
return communicationService.exchangeMessages(StatusResponse.class, podState, StatusResponse statusResponse = communicationService.exchangeMessages(StatusResponse.class, podStateManager,
new OmnipodMessage(podState.getAddress(), messageBlocks, podState.getMessageNumber())); new OmnipodMessage(podStateManager.getAddress(), messageBlocks, podStateManager.getMessageNumber()));
if (deliveryTypes.contains(DeliveryType.TEMP_BASAL)) {
podStateManager.setLastTempBasal(null, null, null);
}
return statusResponse;
} }
} }

View file

@ -3,33 +3,33 @@ package info.nightscout.androidaps.plugins.pump.omnipod.comm.action;
import java.util.List; import java.util.List;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; 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.command.ConfigureAlertsCommand;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; 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.AlertConfiguration;
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.comm.exception.ActionInitializationException;
public class ConfigureAlertsAction implements OmnipodAction<StatusResponse> { public class ConfigureAlertsAction implements OmnipodAction<StatusResponse> {
private final PodSessionState podState; private final PodStateManager podStateManager;
private final List<AlertConfiguration> alertConfigurations; private final List<AlertConfiguration> alertConfigurations;
public ConfigureAlertsAction(PodSessionState podState, List<AlertConfiguration> alertConfigurations) { public ConfigureAlertsAction(PodStateManager podStateManager, List<AlertConfiguration> alertConfigurations) {
if (podState == null) { if (podStateManager == null) {
throw new ActionInitializationException("Pod state cannot be null"); throw new ActionInitializationException("Pod state manager cannot be null");
} }
if (alertConfigurations == null) { if (alertConfigurations == null) {
throw new ActionInitializationException("Alert configurations cannot be null"); throw new ActionInitializationException("Alert configurations cannot be null");
} }
this.podState = podState; this.podStateManager = podStateManager;
this.alertConfigurations = alertConfigurations; this.alertConfigurations = alertConfigurations;
} }
@Override @Override
public StatusResponse execute(OmnipodCommunicationManager communicationService) { public StatusResponse execute(OmnipodCommunicationManager communicationService) {
ConfigureAlertsCommand configureAlertsCommand = new ConfigureAlertsCommand(podState.getCurrentNonce(), alertConfigurations); ConfigureAlertsCommand configureAlertsCommand = new ConfigureAlertsCommand(podStateManager.getCurrentNonce(), alertConfigurations);
StatusResponse statusResponse = communicationService.sendCommand(StatusResponse.class, podState, configureAlertsCommand); StatusResponse statusResponse = communicationService.sendCommand(StatusResponse.class, podStateManager, configureAlertsCommand);
for (AlertConfiguration alertConfiguration : alertConfigurations) { for (AlertConfiguration alertConfiguration : alertConfigurations) {
podState.putConfiguredAlert(alertConfiguration.getAlertSlot(), alertConfiguration.getAlertType()); podStateManager.putConfiguredAlert(alertConfiguration.getAlertSlot(), alertConfiguration.getAlertType());
} }
return statusResponse; return statusResponse;
} }

View file

@ -3,36 +3,36 @@ package info.nightscout.androidaps.plugins.pump.omnipod.comm.action;
import java.util.EnumSet; import java.util.EnumSet;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; 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.command.DeactivatePodCommand;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; 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.DeliveryType;
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.comm.exception.ActionInitializationException;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.PodFaultException;
public class DeactivatePodAction implements OmnipodAction<StatusResponse> { public class DeactivatePodAction implements OmnipodAction<StatusResponse> {
private final PodSessionState podState; private final PodStateManager podStateManager;
private final boolean acknowledgementBeep; private final boolean acknowledgementBeep;
public DeactivatePodAction(PodSessionState podState, boolean acknowledgementBeep) { public DeactivatePodAction(PodStateManager podStateManager, boolean acknowledgementBeep) {
if (podState == null) { if (podStateManager == null) {
throw new ActionInitializationException("Pod state cannot be null"); throw new ActionInitializationException("Pod state manager cannot be null");
} }
this.podState = podState; this.podStateManager = podStateManager;
this.acknowledgementBeep = acknowledgementBeep; this.acknowledgementBeep = acknowledgementBeep;
} }
@Override @Override
public StatusResponse execute(OmnipodCommunicationManager communicationService) { public StatusResponse execute(OmnipodCommunicationManager communicationService) {
if (!podState.isSuspended() && !podState.hasFaultEvent()) { if (!podStateManager.isSuspended() && !podStateManager.hasFaultEvent()) {
try { try {
communicationService.executeAction(new CancelDeliveryAction(podState, communicationService.executeAction(new CancelDeliveryAction(podStateManager,
EnumSet.allOf(DeliveryType.class), acknowledgementBeep)); EnumSet.allOf(DeliveryType.class), acknowledgementBeep));
} catch (PodFaultException ex) { } catch (PodFaultException ex) {
// Ignore // Ignore
} }
} }
return communicationService.sendCommand(StatusResponse.class, podState, new DeactivatePodCommand(podState.getCurrentNonce())); return communicationService.sendCommand(StatusResponse.class, podStateManager, new DeactivatePodCommand(podStateManager.getCurrentNonce()));
} }
} }

View file

@ -1,29 +1,29 @@
package info.nightscout.androidaps.plugins.pump.omnipod.comm.action; 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.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.command.GetStatusCommand;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoResponse; 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.PodInfoType;
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.comm.exception.ActionInitializationException;
public class GetPodInfoAction implements OmnipodAction<PodInfoResponse> { public class GetPodInfoAction implements OmnipodAction<PodInfoResponse> {
private final PodSessionState podState; private final PodStateManager podStateManager;
private final PodInfoType podInfoType; private final PodInfoType podInfoType;
public GetPodInfoAction(PodSessionState podState, PodInfoType podInfoType) { public GetPodInfoAction(PodStateManager podStateManager, PodInfoType podInfoType) {
if (podState == null) { if (podStateManager == null) {
throw new ActionInitializationException("Pod state cannot be null"); throw new ActionInitializationException("Pod state manager cannot be null");
} }
if (podInfoType == null) { if (podInfoType == null) {
throw new ActionInitializationException("Pod info type cannot be null"); throw new ActionInitializationException("Pod info type cannot be null");
} }
this.podState = podState; this.podStateManager = podStateManager;
this.podInfoType = podInfoType; this.podInfoType = podInfoType;
} }
@Override @Override
public PodInfoResponse execute(OmnipodCommunicationManager communicationService) { public PodInfoResponse execute(OmnipodCommunicationManager communicationService) {
return communicationService.sendCommand(PodInfoResponse.class, podState, new GetStatusCommand(podInfoType)); return communicationService.sendCommand(PodInfoResponse.class, podStateManager, new GetStatusCommand(podInfoType));
} }
} }

View file

@ -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.command.GetStatusCommand;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; 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.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.comm.exception.ActionInitializationException;
import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager;
public class GetStatusAction implements OmnipodAction<StatusResponse> { public class GetStatusAction implements OmnipodAction<StatusResponse> {
private final PodSessionState podState; private final PodStateManager podStateManager;
public GetStatusAction(PodSessionState podState) { public GetStatusAction(PodStateManager podState) {
if (podState == null) { 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 @Override
public StatusResponse execute(OmnipodCommunicationManager communicationService) { 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));
} }
} }

View file

@ -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.comm.message.response.StatusResponse;
import info.nightscout.androidaps.plugins.pump.omnipod.defs.SetupProgress; 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.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<StatusResponse> { public class InsertCannulaAction implements OmnipodAction<StatusResponse> {
private final PodSessionState podState; private final PodStateManager podStateManager;
private final InsertCannulaService service; private final InsertCannulaService service;
private final BasalSchedule initialBasalSchedule; private final BasalSchedule initialBasalSchedule;
public InsertCannulaAction(InsertCannulaService insertCannulaService, PodSessionState podState, BasalSchedule initialBasalSchedule) { public InsertCannulaAction(InsertCannulaService insertCannulaService, PodStateManager podStateManager, BasalSchedule initialBasalSchedule) {
if (insertCannulaService == null) { if (insertCannulaService == null) {
throw new ActionInitializationException("Insert cannula service cannot be null"); throw new ActionInitializationException("Insert cannula service cannot be null");
} }
if (podState == null) { if (podStateManager == null) {
throw new ActionInitializationException("Pod state cannot be null"); throw new ActionInitializationException("Pod state manager cannot be null");
} }
if (initialBasalSchedule == null) { if (initialBasalSchedule == null) {
throw new ActionInitializationException("Initial basal schedule cannot be null"); throw new ActionInitializationException("Initial basal schedule cannot be null");
} }
this.service = insertCannulaService; this.service = insertCannulaService;
this.podState = podState; this.podStateManager = podStateManager;
this.initialBasalSchedule = initialBasalSchedule; this.initialBasalSchedule = initialBasalSchedule;
} }
public static void updateCannulaInsertionStatus(PodSessionState podState, StatusResponse statusResponse, AAPSLogger aapsLogger) { public static void updateCannulaInsertionStatus(PodStateManager podStateManager, StatusResponse statusResponse, AAPSLogger aapsLogger) {
if (podState.getSetupProgress().equals(SetupProgress.CANNULA_INSERTING) && if (podStateManager.getSetupProgress().equals(SetupProgress.CANNULA_INSERTING) &&
statusResponse.getPodProgressStatus().isReadyForDelivery()) { statusResponse.getPodProgressStatus().isReadyForDelivery()) {
aapsLogger.debug(LTag.PUMPBTCOMM, "Updating SetupProgress from CANNULA_INSERTING to COMPLETED"); aapsLogger.debug(LTag.PUMPBTCOMM, "Updating SetupProgress from CANNULA_INSERTING to COMPLETED");
podState.setSetupProgress(SetupProgress.COMPLETED); podStateManager.setSetupProgress(SetupProgress.COMPLETED);
} }
} }
@Override @Override
public StatusResponse execute(OmnipodCommunicationManager communicationService) { public StatusResponse execute(OmnipodCommunicationManager communicationService) {
if (podState.getSetupProgress().isBefore(SetupProgress.PRIMING_FINISHED)) { if (!podStateManager.isPaired() || podStateManager.getSetupProgress().isBefore(SetupProgress.PRIMING_FINISHED)) {
throw new IllegalSetupProgressException(SetupProgress.PRIMING_FINISHED, podState.getSetupProgress()); throw new IllegalSetupProgressException(SetupProgress.PRIMING_FINISHED, podStateManager.getSetupProgress());
} }
if (podState.getSetupProgress().isBefore(SetupProgress.INITIAL_BASAL_SCHEDULE_SET)) { if (podStateManager.getSetupProgress().isBefore(SetupProgress.INITIAL_BASAL_SCHEDULE_SET)) {
service.programInitialBasalSchedule(communicationService, podState, initialBasalSchedule); service.programInitialBasalSchedule(communicationService, podStateManager, initialBasalSchedule);
podState.setSetupProgress(SetupProgress.INITIAL_BASAL_SCHEDULE_SET); podStateManager.setSetupProgress(SetupProgress.INITIAL_BASAL_SCHEDULE_SET);
} }
if (podState.getSetupProgress().isBefore(SetupProgress.STARTING_INSERT_CANNULA)) { if (podStateManager.getSetupProgress().isBefore(SetupProgress.STARTING_INSERT_CANNULA)) {
service.executeExpirationRemindersAlertCommand(communicationService, podState); service.executeExpirationRemindersAlertCommand(communicationService, podStateManager);
podState.setSetupProgress(SetupProgress.STARTING_INSERT_CANNULA); podStateManager.setSetupProgress(SetupProgress.STARTING_INSERT_CANNULA);
} }
if (podState.getSetupProgress().isBefore(SetupProgress.CANNULA_INSERTING)) { if (podStateManager.getSetupProgress().isBefore(SetupProgress.CANNULA_INSERTING)) {
StatusResponse statusResponse = service.executeInsertionBolusCommand(communicationService, podState); StatusResponse statusResponse = service.executeInsertionBolusCommand(communicationService, podStateManager);
podState.setSetupProgress(SetupProgress.CANNULA_INSERTING); podStateManager.setSetupProgress(SetupProgress.CANNULA_INSERTING);
return statusResponse; return statusResponse;
} else if (podState.getSetupProgress().equals(SetupProgress.CANNULA_INSERTING)) { } else if (podStateManager.getSetupProgress().equals(SetupProgress.CANNULA_INSERTING)) {
// Check status // Check status
StatusResponse statusResponse = communicationService.executeAction(new GetStatusAction(podState)); StatusResponse statusResponse = communicationService.executeAction(new GetStatusAction(podStateManager));
updateCannulaInsertionStatus(podState, statusResponse, communicationService.aapsLogger); updateCannulaInsertionStatus(podStateManager, statusResponse, communicationService.aapsLogger);
return statusResponse; return statusResponse;
} else { } else {
throw new IllegalSetupProgressException(null, podState.getSetupProgress()); throw new IllegalSetupProgressException(null, podStateManager.getSetupProgress());
} }
} }
} }

View file

@ -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.comm.message.response.StatusResponse;
import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodProgressStatus; 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.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<StatusResponse> { public class PrimeAction implements OmnipodAction<StatusResponse> {
private final PrimeService service; 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) { if (primeService == null) {
throw new ActionInitializationException("Prime service cannot be null"); throw new ActionInitializationException("Prime service cannot be null");
} }
if (podState == null) { if (podStateManager == null) {
throw new ActionInitializationException("Pod state cannot be null"); throw new ActionInitializationException("Pod state manager cannot be null");
} }
this.service = primeService; this.service = primeService;
this.podState = podState; this.podStateManager = podStateManager;
} }
public static void updatePrimingStatus(PodSessionState podState, StatusResponse statusResponse, AAPSLogger aapsLogger) { public static void updatePrimingStatus(PodStateManager podStateManager, StatusResponse statusResponse, AAPSLogger aapsLogger) {
if (podState.getSetupProgress().equals(SetupProgress.PRIMING) && statusResponse.getPodProgressStatus().equals(PodProgressStatus.PRIMING_COMPLETED)) { if (podStateManager.getSetupProgress().equals(SetupProgress.PRIMING) && statusResponse.getPodProgressStatus().equals(PodProgressStatus.PRIMING_COMPLETED)) {
aapsLogger.debug(LTag.PUMPBTCOMM, "Updating SetupProgress from PRIMING to PRIMING_FINISHED"); aapsLogger.debug(LTag.PUMPBTCOMM, "Updating SetupProgress from PRIMING to PRIMING_FINISHED");
podState.setSetupProgress(SetupProgress.PRIMING_FINISHED); podStateManager.setSetupProgress(SetupProgress.PRIMING_FINISHED);
} }
} }
@Override @Override
public StatusResponse execute(OmnipodCommunicationManager communicationService) { public StatusResponse execute(OmnipodCommunicationManager communicationService) {
if (podState.getSetupProgress().isBefore(SetupProgress.POD_CONFIGURED)) { if (podStateManager.getSetupProgress().isBefore(SetupProgress.POD_CONFIGURED)) {
throw new IllegalSetupProgressException(SetupProgress.POD_CONFIGURED, podState.getSetupProgress()); throw new IllegalSetupProgressException(SetupProgress.POD_CONFIGURED, podStateManager.getSetupProgress());
} }
if (podState.getSetupProgress().isBefore(SetupProgress.STARTING_PRIME)) { if (podStateManager.getSetupProgress().isBefore(SetupProgress.STARTING_PRIME)) {
service.executeDisableTab5Sub16FaultConfigCommand(communicationService, podState); service.executeDisableTab5Sub16FaultConfigCommand(communicationService, podStateManager);
service.executeFinishSetupReminderAlertCommand(communicationService, podState); service.executeFinishSetupReminderAlertCommand(communicationService, podStateManager);
podState.setSetupProgress(SetupProgress.STARTING_PRIME); podStateManager.setSetupProgress(SetupProgress.STARTING_PRIME);
} }
if (podState.getSetupProgress().isBefore(SetupProgress.PRIMING)) { if (podStateManager.getSetupProgress().isBefore(SetupProgress.PRIMING)) {
StatusResponse statusResponse = service.executePrimeBolusCommand(communicationService, podState); StatusResponse statusResponse = service.executePrimeBolusCommand(communicationService, podStateManager);
podState.setSetupProgress(SetupProgress.PRIMING); podStateManager.setSetupProgress(SetupProgress.PRIMING);
return statusResponse; return statusResponse;
} else if (podState.getSetupProgress().equals(SetupProgress.PRIMING)) { } else if (podStateManager.getSetupProgress().equals(SetupProgress.PRIMING)) {
// Check status // Check status
StatusResponse statusResponse = communicationService.executeAction(new GetStatusAction(podState)); StatusResponse statusResponse = communicationService.executeAction(new GetStatusAction(podStateManager));
updatePrimingStatus(podState, statusResponse, communicationService.aapsLogger); updatePrimingStatus(podStateManager, statusResponse, communicationService.aapsLogger);
return statusResponse; return statusResponse;
} else { } else {
throw new IllegalSetupProgressException(null, podState.getSetupProgress()); throw new IllegalSetupProgressException(null, podStateManager.getSetupProgress());
} }
} }
} }

View file

@ -5,25 +5,25 @@ import org.joda.time.Duration;
import java.util.Arrays; import java.util.Arrays;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; 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.OmnipodMessage;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.BasalScheduleExtraCommand; 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.command.SetInsulinScheduleCommand;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; 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.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.comm.exception.ActionInitializationException;
public class SetBasalScheduleAction implements OmnipodAction<StatusResponse> { public class SetBasalScheduleAction implements OmnipodAction<StatusResponse> {
private final PodSessionState podState; private final PodStateManager podStateManager;
private final BasalSchedule basalSchedule; private final BasalSchedule basalSchedule;
private final boolean confidenceReminder; private final boolean confidenceReminder;
private final Duration scheduleOffset; private final Duration scheduleOffset;
private final boolean acknowledgementBeep; private final boolean acknowledgementBeep;
public SetBasalScheduleAction(PodSessionState podState, BasalSchedule basalSchedule, public SetBasalScheduleAction(PodStateManager podStateManager, BasalSchedule basalSchedule,
boolean confidenceReminder, Duration scheduleOffset, boolean acknowledgementBeep) { boolean confidenceReminder, Duration scheduleOffset, boolean acknowledgementBeep) {
if (podState == null) { if (podStateManager == null) {
throw new ActionInitializationException("Pod state cannot be null"); throw new ActionInitializationException("Pod state manager cannot be null");
} }
if (basalSchedule == null) { if (basalSchedule == null) {
throw new ActionInitializationException("Basal schedule cannot be null"); throw new ActionInitializationException("Basal schedule cannot be null");
@ -31,7 +31,7 @@ public class SetBasalScheduleAction implements OmnipodAction<StatusResponse> {
if (scheduleOffset == null) { if (scheduleOffset == null) {
throw new ActionInitializationException("Schedule offset cannot be null"); throw new ActionInitializationException("Schedule offset cannot be null");
} }
this.podState = podState; this.podStateManager = podStateManager;
this.basalSchedule = basalSchedule; this.basalSchedule = basalSchedule;
this.confidenceReminder = confidenceReminder; this.confidenceReminder = confidenceReminder;
this.scheduleOffset = scheduleOffset; this.scheduleOffset = scheduleOffset;
@ -40,14 +40,14 @@ public class SetBasalScheduleAction implements OmnipodAction<StatusResponse> {
@Override @Override
public StatusResponse execute(OmnipodCommunicationManager communicationService) { 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, BasalScheduleExtraCommand extraCommand = new BasalScheduleExtraCommand(basalSchedule, scheduleOffset,
acknowledgementBeep, confidenceReminder, Duration.ZERO); acknowledgementBeep, confidenceReminder, Duration.ZERO);
OmnipodMessage basalMessage = new OmnipodMessage(podState.getAddress(), Arrays.asList(setBasal, extraCommand), OmnipodMessage basalMessage = new OmnipodMessage(podStateManager.getAddress(), Arrays.asList(setBasal, extraCommand),
podState.getMessageNumber()); podStateManager.getMessageNumber());
StatusResponse statusResponse = communicationService.exchangeMessages(StatusResponse.class, podState, basalMessage); StatusResponse statusResponse = communicationService.exchangeMessages(StatusResponse.class, podStateManager, basalMessage);
podState.setBasalSchedule(basalSchedule); podStateManager.setBasalSchedule(basalSchedule);
return statusResponse; return statusResponse;
} }
} }

View file

@ -1,35 +1,37 @@
package info.nightscout.androidaps.plugins.pump.omnipod.comm.action; package info.nightscout.androidaps.plugins.pump.omnipod.comm.action;
import org.joda.time.DateTime;
import org.joda.time.Duration; import org.joda.time.Duration;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; 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.MessageBlock;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.OmnipodMessage; 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.SetInsulinScheduleCommand;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.TempBasalExtraCommand; 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.comm.message.response.StatusResponse;
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.comm.exception.ActionInitializationException; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst;
public class SetTempBasalAction implements OmnipodAction<StatusResponse> { public class SetTempBasalAction implements OmnipodAction<StatusResponse> {
private final PodSessionState podState; private final PodStateManager podStateManager;
private final double rate; private final double rate;
private final Duration duration; private final Duration duration;
private final boolean acknowledgementBeep; private final boolean acknowledgementBeep;
private final boolean completionBeep; private final boolean completionBeep;
public SetTempBasalAction(PodSessionState podState, double rate, Duration duration, public SetTempBasalAction(PodStateManager podStateManager, double rate, Duration duration,
boolean acknowledgementBeep, boolean completionBeep) { boolean acknowledgementBeep, boolean completionBeep) {
if (podState == null) { if (podStateManager == null) {
throw new ActionInitializationException("Pod state cannot be null"); throw new ActionInitializationException("Pod state manager cannot be null");
} }
if (duration == null) { if (duration == null) {
throw new ActionInitializationException("Duration cannot be null"); throw new ActionInitializationException("Duration cannot be null");
} }
this.podState = podState; this.podStateManager = podStateManager;
this.rate = rate; this.rate = rate;
this.duration = duration; this.duration = duration;
this.acknowledgementBeep = acknowledgementBeep; this.acknowledgementBeep = acknowledgementBeep;
@ -39,10 +41,12 @@ public class SetTempBasalAction implements OmnipodAction<StatusResponse> {
@Override @Override
public StatusResponse execute(OmnipodCommunicationManager communicationService) { public StatusResponse execute(OmnipodCommunicationManager communicationService) {
List<MessageBlock> messageBlocks = Arrays.asList( // List<MessageBlock> messageBlocks = Arrays.asList( //
new SetInsulinScheduleCommand(podState.getCurrentNonce(), rate, duration), new SetInsulinScheduleCommand(podStateManager.getCurrentNonce(), rate, duration),
new TempBasalExtraCommand(rate, duration, acknowledgementBeep, completionBeep, Duration.ZERO)); new TempBasalExtraCommand(rate, duration, acknowledgementBeep, completionBeep, Duration.ZERO));
OmnipodMessage message = new OmnipodMessage(podState.getAddress(), messageBlocks, podState.getMessageNumber()); OmnipodMessage message = new OmnipodMessage(podStateManager.getAddress(), messageBlocks, podStateManager.getMessageNumber());
return communicationService.exchangeMessages(StatusResponse.class, podState, 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;
} }
} }

View file

@ -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.PacketType;
import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodProgressStatus; 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.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; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst;
public class SetupPodAction implements OmnipodAction<VersionResponse> { public class SetupPodAction implements OmnipodAction<VersionResponse> {
private final PodSessionState podState; private final PodStateManager podStateManager;
public SetupPodAction(PodSessionState podState) { public SetupPodAction(PodStateManager podStateManager) {
this.podState = podState; if(podStateManager == null) {
throw new IllegalArgumentException("Pod state manager can not be null");
}
this.podStateManager = podStateManager;
} }
@Override @Override
public VersionResponse execute(OmnipodCommunicationManager communicationService) { public VersionResponse execute(OmnipodCommunicationManager communicationService) {
if (!podState.getSetupProgress().equals(SetupProgress.ADDRESS_ASSIGNED)) { if (!podStateManager.getSetupProgress().equals(SetupProgress.ADDRESS_ASSIGNED)) {
throw new IllegalSetupProgressException(SetupProgress.ADDRESS_ASSIGNED, podState.getSetupProgress()); 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, SetupPodCommand setupPodCommand = new SetupPodCommand(podStateManager.getAddress(), activationDate,
podState.getLot(), podState.getTid()); podStateManager.getLot(), podStateManager.getTid());
OmnipodMessage message = new OmnipodMessage(OmnipodConst.DEFAULT_ADDRESS, OmnipodMessage message = new OmnipodMessage(OmnipodConst.DEFAULT_ADDRESS,
Collections.singletonList(setupPodCommand), podState.getMessageNumber()); Collections.singletonList(setupPodCommand), podStateManager.getMessageNumber());
VersionResponse setupPodResponse; VersionResponse setupPodResponse;
try { try {
setupPodResponse = communicationService.exchangeMessages(VersionResponse.class, podState, setupPodResponse = communicationService.exchangeMessages(VersionResponse.class, podStateManager,
message, OmnipodConst.DEFAULT_ADDRESS, podState.getAddress()); message, OmnipodConst.DEFAULT_ADDRESS, podStateManager.getAddress());
} catch (IllegalPacketTypeException ex) { } catch (IllegalPacketTypeException ex) {
if (PacketType.ACK.equals(ex.getActual())) { if (PacketType.ACK.equals(ex.getActual())) {
// Pod is already configured // Pod is already configured
podState.setSetupProgress(SetupProgress.POD_CONFIGURED); podStateManager.setSetupProgress(SetupProgress.POD_CONFIGURED);
return null; return null;
} }
throw ex; throw ex;
@ -53,14 +56,14 @@ public class SetupPodAction implements OmnipodAction<VersionResponse> {
if (!setupPodResponse.isSetupPodVersionResponse()) { if (!setupPodResponse.isSetupPodVersionResponse()) {
throw new IllegalVersionResponseTypeException("setupPod", "assignAddress"); throw new IllegalVersionResponseTypeException("setupPod", "assignAddress");
} }
if (setupPodResponse.getAddress() != podState.getAddress()) { if (setupPodResponse.getAddress() != podStateManager.getAddress()) {
throw new IllegalMessageAddressException(podState.getAddress(), setupPodResponse.getAddress()); throw new IllegalMessageAddressException(podStateManager.getAddress(), setupPodResponse.getAddress());
} }
if (setupPodResponse.getPodProgressStatus() != PodProgressStatus.PAIRING_COMPLETED) { if (setupPodResponse.getPodProgressStatus() != PodProgressStatus.PAIRING_COMPLETED) {
throw new IllegalPodProgressException(PodProgressStatus.PAIRING_COMPLETED, setupPodResponse.getPodProgressStatus()); throw new IllegalPodProgressException(PodProgressStatus.PAIRING_COMPLETED, setupPodResponse.getPodProgressStatus());
} }
podState.setSetupProgress(SetupProgress.POD_CONFIGURED); podStateManager.setSetupProgress(SetupProgress.POD_CONFIGURED);
return setupPodResponse; return setupPodResponse;
} }

View file

@ -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.AlertConfiguration;
import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertConfigurationFactory; 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.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; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst;
public class InsertCannulaService { public class InsertCannulaService {
public StatusResponse programInitialBasalSchedule(OmnipodCommunicationManager communicationService, public StatusResponse programInitialBasalSchedule(OmnipodCommunicationManager communicationService,
PodSessionState podState, BasalSchedule basalSchedule) { PodStateManager podStateManager, BasalSchedule basalSchedule) {
return communicationService.executeAction(new SetBasalScheduleAction(podState, basalSchedule, return communicationService.executeAction(new SetBasalScheduleAction(podStateManager, basalSchedule,
true, podState.getScheduleOffset(), false)); true, podStateManager.getScheduleOffset(), false));
} }
public StatusResponse executeExpirationRemindersAlertCommand(OmnipodCommunicationManager communicationService, public StatusResponse executeExpirationRemindersAlertCommand(OmnipodCommunicationManager communicationService,
PodSessionState podState) { PodStateManager podStateManager) {
AlertConfiguration lowReservoirAlertConfiguration = AlertConfigurationFactory.createLowReservoirAlertConfiguration(OmnipodConst.LOW_RESERVOIR_ALERT); 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(), Duration timeUntilExpirationAdvisoryAlarm = new Duration(DateTime.now(),
endOfServiceTime.minus(OmnipodConst.EXPIRATION_ADVISORY_WINDOW)); endOfServiceTime.minus(OmnipodConst.EXPIRATION_ADVISORY_WINDOW));
@ -49,11 +49,11 @@ public class InsertCannulaService {
autoOffAlertConfiguration // autoOffAlertConfiguration //
); );
return new ConfigureAlertsAction(podState, alertConfigurations).execute(communicationService); return new ConfigureAlertsAction(podStateManager, alertConfigurations).execute(communicationService);
} }
public StatusResponse executeInsertionBolusCommand(OmnipodCommunicationManager communicationService, PodSessionState podState) { public StatusResponse executeInsertionBolusCommand(OmnipodCommunicationManager communicationService, PodStateManager podStateManager) {
return communicationService.executeAction(new BolusAction(podState, OmnipodConst.POD_CANNULA_INSERTION_BOLUS_UNITS, return communicationService.executeAction(new BolusAction(podStateManager, OmnipodConst.POD_CANNULA_INSERTION_BOLUS_UNITS,
Duration.standardSeconds(1), false, false)); Duration.standardSeconds(1), false, false));
} }
} }

View file

@ -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.comm.message.response.StatusResponse;
import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertConfiguration; 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.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; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst;
public class PrimeService { public class PrimeService {
public StatusResponse executeDisableTab5Sub16FaultConfigCommand(OmnipodCommunicationManager communicationService, PodSessionState podState) { public StatusResponse executeDisableTab5Sub16FaultConfigCommand(OmnipodCommunicationManager communicationService, PodStateManager podStateManager) {
FaultConfigCommand faultConfigCommand = new FaultConfigCommand(podState.getCurrentNonce(), (byte) 0x00, (byte) 0x00); FaultConfigCommand faultConfigCommand = new FaultConfigCommand(podStateManager.getCurrentNonce(), (byte) 0x00, (byte) 0x00);
OmnipodMessage faultConfigMessage = new OmnipodMessage(podState.getAddress(), OmnipodMessage faultConfigMessage = new OmnipodMessage(podStateManager.getAddress(),
Collections.singletonList(faultConfigCommand), podState.getMessageNumber()); Collections.singletonList(faultConfigCommand), podStateManager.getMessageNumber());
return communicationService.exchangeMessages(StatusResponse.class, podState, faultConfigMessage); 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(); AlertConfiguration finishSetupReminderAlertConfiguration = AlertConfigurationFactory.createFinishSetupReminderAlertConfiguration();
return communicationService.executeAction(new ConfigureAlertsAction(podState, return communicationService.executeAction(new ConfigureAlertsAction(podStateManager,
Collections.singletonList(finishSetupReminderAlertConfiguration))); Collections.singletonList(finishSetupReminderAlertConfiguration)));
} }
public StatusResponse executePrimeBolusCommand(OmnipodCommunicationManager communicationService, PodSessionState podState) { public StatusResponse executePrimeBolusCommand(OmnipodCommunicationManager communicationService, PodStateManager podStateManager) {
return communicationService.executeAction(new BolusAction(podState, OmnipodConst.POD_PRIME_BOLUS_UNITS, return communicationService.executeAction(new BolusAction(podStateManager, OmnipodConst.POD_PRIME_BOLUS_UNITS,
Duration.standardSeconds(1), false, false)); Duration.standardSeconds(1), false, false));
} }
} }

View file

@ -15,8 +15,12 @@ public class AlertSet {
} }
} }
public AlertSet(AlertSet alertSet) {
this(alertSet == null ? new ArrayList<>() : alertSet.getAlertSlots());
}
public AlertSet(List<AlertSlot> alertSlots) { public AlertSet(List<AlertSlot> alertSlots) {
this.alertSlots = alertSlots; this.alertSlots = alertSlots == null ? new ArrayList<>() : new ArrayList<>(alertSlots);
} }
public List<AlertSlot> getAlertSlots() { public List<AlertSlot> getAlertSlots() {

View file

@ -71,9 +71,5 @@ public interface OmnipodCommunicationManagerInterface {
*/ */
PumpEnactResult setTime(); PumpEnactResult setTime();
void setPumpStatus(OmnipodPumpStatus pumpStatusLocal);
PodInfoRecentPulseLog readPulseLog(); PodInfoRecentPulseLog readPulseLog();
} }

View file

@ -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<AlertSlot, AlertType> 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 +
'}';
}
}

View file

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

View file

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

View file

@ -1,6 +0,0 @@
package info.nightscout.androidaps.plugins.pump.omnipod.defs.state;
@FunctionalInterface
public interface PodStateChangedHandler {
void handle(PodSessionState podState);
}

View file

@ -0,0 +1,754 @@
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 net.danlew.android.joda.JodaTimeAndroid;
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;
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.util.OmniCRC;
import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst;
import info.nightscout.androidaps.utils.DateUtil;
public abstract class PodStateManager {
private final AAPSLogger aapsLogger;
private final Gson gsonInstance;
private PodState podState;
public PodStateManager(AAPSLogger aapsLogger) {
this.aapsLogger = aapsLogger;
this.gsonInstance = createGson();
}
public final boolean hasState() {
return podState != null;
}
public final void removeState() {
this.podState = null;
storePodState();
notifyPodStateChanged();
}
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();
}
public final boolean isPaired() {
return hasState() //
&& podState.getLot() != null && podState.getTid() != null //
&& podState.getPiVersion() != null && podState.getPmVersion() != null //
&& podState.getTimeZone() != null //
&& podState.getSetupProgress() != null;
}
public final boolean isSetupCompleted() {
return isPaired() && SetupProgress.COMPLETED.equals(podState.getSetupProgress());
}
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");
}
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);
});
}
public final int getAddress() {
return getSafe(() -> podState.getAddress());
}
public final int getMessageNumber() {
return getSafe(() -> podState.getMessageNumber());
}
public final void setMessageNumber(int messageNumber) {
setAndStore(() -> podState.setMessageNumber(messageNumber));
}
public final int getPacketNumber() {
return getSafe(() -> podState.getPacketNumber());
}
public final void setPacketNumber(int packetNumber) {
setAndStore(() -> podState.setPacketNumber(packetNumber));
}
public final void increaseMessageNumber() {
setAndStore(() -> podState.setMessageNumber((podState.getMessageNumber() + 1) & 0b1111));
}
public final void increasePacketNumber() {
setAndStore(() -> podState.setPacketNumber((podState.getPacketNumber() + 1) & 0b11111));
}
public final 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));
}
public final synchronized int getCurrentNonce() {
if (!isPaired()) {
throw new IllegalStateException("Cannot get current nonce: Pod is not paired yet");
}
return podState.getNonceState().getCurrentNonce();
}
public final synchronized void advanceToNextNonce() {
if (!isPaired()) {
throw new IllegalStateException("Cannot advance to next nonce: Pod is not paired yet");
}
setAndStore(() -> podState.getNonceState().advanceToNextNonce());
}
public final DateTime getLastSuccessfulCommunication() {
return getSafe(() -> podState.getLastSuccessfulCommunication());
}
public final void setLastSuccessfulCommunication(DateTime dateTime) {
setAndStore(() -> podState.setLastSuccessfulCommunication(dateTime));
}
public final DateTime getLastFailedCommunication() {
return getSafe(() -> podState.getLastFailedCommunication());
}
public final void setLastFailedCommunication(DateTime dateTime) {
setAndStore(() -> podState.setLastFailedCommunication(dateTime));
}
public final boolean hasFaultEvent() {
return getSafe(() -> podState.getFaultEvent()) != null;
}
public final PodInfoFaultEvent getFaultEvent() {
return getSafe(() -> podState.getFaultEvent());
}
public final void setFaultEvent(PodInfoFaultEvent faultEvent) {
setAndStore(() -> podState.setFaultEvent(faultEvent));
}
public final AlertType getConfiguredAlertType(AlertSlot alertSlot) {
return getSafe(() -> podState.getConfiguredAlerts().get(alertSlot));
}
public final void putConfiguredAlert(AlertSlot alertSlot, AlertType alertType) {
setAndStore(() -> podState.getConfiguredAlerts().put(alertSlot, alertType));
}
public final void removeConfiguredAlert(AlertSlot alertSlot) {
setAndStore(() -> podState.getConfiguredAlerts().remove(alertSlot));
}
public final boolean hasActiveAlerts() {
AlertSet activeAlerts = podState.getActiveAlerts();
return activeAlerts != null && activeAlerts.size() > 0;
}
public final AlertSet getActiveAlerts() {
return new AlertSet(getSafe(() -> podState.getActiveAlerts()));
}
public final Integer getLot() {
return getSafe(() -> podState.getLot());
}
public final Integer getTid() {
return getSafe(() -> podState.getTid());
}
public final FirmwareVersion getPiVersion() {
return getSafe(() -> podState.getPiVersion());
}
public final FirmwareVersion getPmVersion() {
return getSafe(() -> podState.getPmVersion());
}
public final DateTimeZone getTimeZone() {
return getSafe(() -> podState.getTimeZone());
}
public final void setTimeZone(DateTimeZone timeZone) {
if (timeZone == null) {
throw new IllegalArgumentException("Time zone can not be null");
}
setAndStore(() -> podState.setTimeZone(timeZone));
}
public final DateTime getTime() {
DateTime now = DateTime.now();
return now.withZone(getSafe(() -> podState.getTimeZone()));
}
public final DateTime getActivatedAt() {
DateTime activatedAt = getSafe(() -> podState.getActivatedAt());
return activatedAt == null ? null : activatedAt.withZone(getSafe(() -> podState.getTimeZone()));
}
public final DateTime getExpiresAt() {
DateTime expiresAt = getSafe(() -> podState.getExpiresAt());
return expiresAt == null ? null : expiresAt.withZone(getSafe(() -> podState.getTimeZone()));
}
// 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> T getSafe(Supplier<T> 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>) (dateTime, typeOfSrc, context) ->
new JsonPrimitive(ISODateTimeFormat.dateTime().print(dateTime)))
.registerTypeAdapter(DateTime.class, (JsonDeserializer<DateTime>) (json, typeOfT, context) ->
ISODateTimeFormat.dateTime().parseDateTime(json.getAsString()))
.registerTypeAdapter(DateTimeZone.class, (JsonSerializer<DateTimeZone>) (timeZone, typeOfSrc, context) ->
new JsonPrimitive(timeZone.getID()))
.registerTypeAdapter(DateTimeZone.class, (JsonDeserializer<DateTimeZone>) (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<AlertSlot, AlertType> 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<AlertSlot, AlertType> 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<T> when min API level >= 24
@FunctionalInterface
private interface Supplier<T> {
T get();
}
}

View file

@ -15,6 +15,7 @@ import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction
import info.nightscout.androidaps.plugins.pump.omnipod.defs.SetupProgress 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.defs.PodActionType
import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.model.FullInitPodWizardModel import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.model.FullInitPodWizardModel
import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.model.RemovePodWizardModel import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.model.RemovePodWizardModel
@ -42,10 +43,10 @@ class PodManagementActivity : NoSplashAppCompatActivity() {
@Inject lateinit var fabricPrivacy: FabricPrivacy @Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var commandQueue: CommandQueueProvider @Inject lateinit var commandQueue: CommandQueueProvider
@Inject lateinit var omnipodUtil: OmnipodUtil @Inject lateinit var omnipodUtil: OmnipodUtil
@Inject lateinit var podStateManager: PodStateManager
@Inject lateinit var injector: HasAndroidInjector @Inject lateinit var injector: HasAndroidInjector
private var initPodChanged = false private var initPodChanged = false
private var podSessionFullyInitalized = false
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -99,8 +100,7 @@ class PodManagementActivity : NoSplashAppCompatActivity() {
wizardPagerContext.clearContext() wizardPagerContext.clearContext()
wizardPagerContext.pagerSettings = pagerSettings wizardPagerContext.pagerSettings = pagerSettings
val podSessionState = omnipodUtil.getPodSessionState() val isFullInit = !podStateManager.isPaired || podStateManager.setupProgress.isBefore(SetupProgress.PRIMING_FINISHED)
val isFullInit = podSessionState == null || podSessionState.setupProgress.isBefore(SetupProgress.PRIMING_FINISHED)
if (isFullInit) { if (isFullInit) {
wizardPagerContext.wizardModel = FullInitPodWizardModel(applicationContext) wizardPagerContext.wizardModel = FullInitPodWizardModel(applicationContext)
} else { } else {
@ -151,13 +151,11 @@ class PodManagementActivity : NoSplashAppCompatActivity() {
} }
fun refreshButtons() { fun refreshButtons() {
initpod_init_pod.isEnabled = (omnipodUtil.getPodSessionState() == null || initpod_init_pod.isEnabled = !podStateManager.isPaired() ||
omnipodUtil.getPodSessionState().getSetupProgress().isBefore(SetupProgress.COMPLETED)) podStateManager.getSetupProgress().isBefore(SetupProgress.COMPLETED)
val isPodSessionActive = (omnipodUtil.getPodSessionState() != null) initpod_remove_pod.isEnabled = podStateManager.hasState() && podStateManager.isPaired
initpod_reset_pod.isEnabled = podStateManager.hasState()
initpod_remove_pod.isEnabled = isPodSessionActive
initpod_reset_pod.isEnabled = isPodSessionActive || omnipodUtil.hasNextPodAddress()
if (omnipodUtil.getDriverState() == OmnipodDriverState.NotInitalized) { if (omnipodUtil.getDriverState() == OmnipodDriverState.NotInitalized) {
// if rileylink is not running we disable all operations // if rileylink is not running we disable all operations

View file

@ -16,6 +16,7 @@ import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag; import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; 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.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.PodManagementActivity;
import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.defs.PodActionType; import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.defs.PodActionType;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodDriverState; import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodDriverState;
@ -33,6 +34,7 @@ public class InitPodRefreshAction extends AbstractCancelAction implements Finish
private PodActionType actionType; private PodActionType actionType;
@Inject OmnipodUtil omnipodUtil; @Inject OmnipodUtil omnipodUtil;
@Inject PodStateManager podStateManager;
@Inject AAPSLogger aapsLogger; @Inject AAPSLogger aapsLogger;
@Inject SP sp; @Inject SP sp;
@ -58,7 +60,7 @@ public class InitPodRefreshAction extends AbstractCancelAction implements Finish
@Override @Override
public void execute() { public void execute() {
if (actionType == PodActionType.InitPod) { if (actionType == PodActionType.InitPod) {
if (omnipodUtil.getPodSessionState().getSetupProgress().isBefore(SetupProgress.COMPLETED)) { if (podStateManager.getSetupProgress().isBefore(SetupProgress.COMPLETED)) {
omnipodUtil.setDriverState(OmnipodDriverState.Initalized_PodInitializing); omnipodUtil.setDriverState(OmnipodDriverState.Initalized_PodInitializing);
} else { } else {
omnipodUtil.setDriverState(OmnipodDriverState.Initalized_PodAttached); omnipodUtil.setDriverState(OmnipodDriverState.Initalized_PodAttached);

View file

@ -19,7 +19,7 @@ import javax.inject.Inject;
import dagger.android.support.DaggerFragment; import dagger.android.support.DaggerFragment;
import info.nightscout.androidaps.R; 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; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil;
@ -30,6 +30,7 @@ public class PodInfoFragment extends DaggerFragment {
private static final String ARG_KEY = "key"; private static final String ARG_KEY = "key";
@Inject OmnipodUtil omnipodUtil; @Inject OmnipodUtil omnipodUtil;
@Inject PodStateManager podStateManager;
private PageFragmentCallbacks mCallbacks; private PageFragmentCallbacks mCallbacks;
private String mKey; private String mKey;
@ -84,28 +85,24 @@ public class PodInfoFragment extends DaggerFragment {
} }
private boolean createDataOfPod() { private boolean createDataOfPod() {
if (podStateManager == null)
PodSessionState podSessionState = omnipodUtil.getPodSessionState();
// 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)
return false; return false;
mCurrentReviewItems = new ArrayList<>(); mCurrentReviewItems = new ArrayList<>();
mCurrentReviewItems.add(new ReviewItem("Pod Address", "" + podSessionState.getAddress(), "33")); mCurrentReviewItems.add(new ReviewItem("Pod Address", "" + podStateManager.getAddress(), "33"));
mCurrentReviewItems.add(new ReviewItem("Activated At", podSessionState.getActivatedAt().toString("dd.MM.yyyy HH:mm:ss"), "34")); mCurrentReviewItems.add(new ReviewItem("Activated At", podStateManager.getActivatedAt() == null ? "Not activated yet" : podStateManager.getActivatedAt().toString("dd.MM.yyyy HH:mm:ss"), "34"));
mCurrentReviewItems.add(new ReviewItem("Firmware Version", podSessionState.getPiVersion().toString(), "35")); if (podStateManager.getLot() != null) {
mCurrentReviewItems.add(new ReviewItem("LOT", "" + podSessionState.getLot(), "36")); 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; return true;
} }

View file

@ -15,9 +15,7 @@ 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.RileyLinkServiceState;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice;
import info.nightscout.androidaps.plugins.pump.medtronic.defs.PumpDeviceState; 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.PodDeviceState;
import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodSessionState;
import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodDeviceStatusChange; 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.OmnipodConst;
import info.nightscout.androidaps.utils.resources.ResourceHelper; import info.nightscout.androidaps.utils.resources.ResourceHelper;
@ -47,13 +45,13 @@ public class OmnipodPumpStatus extends PumpStatus {
public Double tempBasalAmount = 0.0d; public Double tempBasalAmount = 0.0d;
public Integer tempBasalLength; public Integer tempBasalLength;
public long tempBasalPumpId; public long tempBasalPumpId;
public PodSessionState podSessionState;
public PumpType pumpType; public PumpType pumpType;
public String regexMac = "([\\da-fA-F]{1,2}(?:\\:|$)){6}"; public String regexMac = "([\\da-fA-F]{1,2}(?:\\:|$)){6}";
public String podNumber; public String podNumber;
public PodDeviceState podDeviceState = PodDeviceState.NeverContacted; public PodDeviceState podDeviceState = PodDeviceState.NeverContacted;
// FIXME replace with method calls on PodStateManager
public boolean podAvailable = false; public boolean podAvailable = false;
public boolean podAvailibityChecked = false; public boolean podAvailibityChecked = false;
public boolean ackAlertsAvailable = false; public boolean ackAlertsAvailable = false;
@ -142,7 +140,6 @@ public class OmnipodPumpStatus extends PumpStatus {
", tempBasalEnd=" + tempBasalEnd + ", tempBasalEnd=" + tempBasalEnd +
", tempBasalAmount=" + tempBasalAmount + ", tempBasalAmount=" + tempBasalAmount +
", tempBasalLength=" + tempBasalLength + ", tempBasalLength=" + tempBasalLength +
", podSessionState=" + podSessionState +
", regexMac='" + regexMac + '\'' + ", regexMac='" + regexMac + '\'' +
", podNumber='" + podNumber + '\'' + ", podNumber='" + podNumber + '\'' +
", podDeviceState=" + podDeviceState + ", podDeviceState=" + podDeviceState +

View file

@ -1,16 +1,13 @@
package info.nightscout.androidaps.plugins.pump.omnipod.driver.comm; package info.nightscout.androidaps.plugins.pump.omnipod.driver.comm;
import android.content.Intent; import android.content.Intent;
import android.text.TextUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.joda.time.Duration; import org.joda.time.Duration;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Objects;
import dagger.android.HasAndroidInjector; import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.MainApp; 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.Source;
import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.events.Event; import info.nightscout.androidaps.events.Event;
import info.nightscout.androidaps.events.EventRefreshOverview;
import info.nightscout.androidaps.interfaces.ActivePluginProvider; import info.nightscout.androidaps.interfaces.ActivePluginProvider;
import info.nightscout.androidaps.interfaces.TreatmentsInterface; import info.nightscout.androidaps.interfaces.TreatmentsInterface;
import info.nightscout.androidaps.logging.AAPSLogger; 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.events.EventOverviewBolusProgress;
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification; 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.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.defs.PumpType;
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil; import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil;
@ -60,8 +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.StatusResponse;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoRecentPulseLog; 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.comm.message.response.podinfo.PodInfoResponse;
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.FaultEventCode;
import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodCommunicationManagerInterface; import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodCommunicationManagerInterface;
import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType; import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType;
@ -69,12 +62,10 @@ 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.PodInitReceiver;
import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BasalSchedule; 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.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.OmnipodPumpStatus;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.db.PodHistory; 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.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.exception.OmnipodException;
import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil;
import info.nightscout.androidaps.utils.resources.ResourceHelper; import info.nightscout.androidaps.utils.resources.ResourceHelper;
@ -83,6 +74,7 @@ import io.reactivex.disposables.Disposable;
public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface { public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface {
private final PodStateManager podStateManager;
private OmnipodUtil omnipodUtil; private OmnipodUtil omnipodUtil;
private AAPSLogger aapsLogger; private AAPSLogger aapsLogger;
private RxBusWrapper rxBus; private RxBusWrapper rxBus;
@ -95,15 +87,12 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface
private static AapsOmnipodManager instance; private static AapsOmnipodManager instance;
private Date lastBolusTime;
private Double lastBolusUnits;
public static AapsOmnipodManager getInstance() { public static AapsOmnipodManager getInstance() {
return instance; return instance;
} }
public AapsOmnipodManager(OmnipodCommunicationManager communicationService, public AapsOmnipodManager(OmnipodCommunicationManager communicationService,
PodSessionState podState, PodStateManager podStateManager,
OmnipodPumpStatus _pumpStatus, OmnipodPumpStatus _pumpStatus,
OmnipodUtil omnipodUtil, OmnipodUtil omnipodUtil,
AAPSLogger aapsLogger, AAPSLogger aapsLogger,
@ -112,6 +101,10 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface
ResourceHelper resourceHelper, ResourceHelper resourceHelper,
HasAndroidInjector injector, HasAndroidInjector injector,
ActivePluginProvider activePlugin) { ActivePluginProvider activePlugin) {
if (podStateManager == null) {
throw new IllegalArgumentException("Pod state manager can not be null");
}
this.podStateManager = podStateManager;
this.omnipodUtil = omnipodUtil; this.omnipodUtil = omnipodUtil;
this.aapsLogger = aapsLogger; this.aapsLogger = aapsLogger;
this.rxBus = rxBus; this.rxBus = rxBus;
@ -120,76 +113,12 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface
this.activePlugin = activePlugin; this.activePlugin = activePlugin;
this.pumpStatus = _pumpStatus; this.pumpStatus = _pumpStatus;
delegate = new OmnipodManager(aapsLogger, sp, communicationService, podState, podSessionState -> { delegate = new OmnipodManager(aapsLogger, sp, communicationService, podStateManager);
// Handle pod state changes
omnipodUtil.setPodSessionState(podSessionState);
updatePumpStatus(podSessionState);
});
instance = this; instance = this;
} }
private void updatePumpStatus(PodSessionState podSessionState) { public PodStateManager getPodStateManager() {
if (pumpStatus != null) { return podStateManager;
if (podSessionState == null) {
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 (podSessionState.hasActiveAlerts()) {
List<String> alerts = translateActiveAlerts(podSessionState);
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, podSessionState.getReservoirLevel())
|| podSessionState.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;
sendEvent(new EventOmnipodPumpValuesChanged());
if (podSessionState.isSuspended() != PumpStatusType.Suspended.equals(pumpStatus.pumpStatusType)) {
sendEvent(new EventRefreshOverview("Omnipod Pump", false));
}
}
}
}
}
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<String> translateActiveAlerts(PodSessionState podSessionState) {
List<String> alerts = new ArrayList<>();
for (AlertSlot alertSlot : podSessionState.getActiveAlerts().getAlertSlots()) {
alerts.add(translateAlertType(podSessionState.getConfiguredAlertType(alertSlot)));
}
return alerts;
} }
@Override @Override
@ -197,13 +126,9 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
if (PodInitActionType.PairAndPrimeWizardStep.equals(podInitActionType)) { if (PodInitActionType.PairAndPrimeWizardStep.equals(podInitActionType)) {
try { try {
int address = obtainNextPodAddress(); Disposable disposable = delegate.pairAndPrime().subscribe(res -> //
Disposable disposable = delegate.pairAndPrime(address).subscribe(res -> //
handleSetupActionResult(podInitActionType, podInitReceiver, res, time, null)); handleSetupActionResult(podInitActionType, podInitReceiver, res, time, null));
removeNextPodAddress();
return new PumpEnactResult(injector).success(true).enacted(true); return new PumpEnactResult(injector).success(true).enacted(true);
} catch (Exception ex) { } catch (Exception ex) {
String comment = handleAndTranslateException(ex); String comment = handleAndTranslateException(ex);
@ -265,8 +190,6 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface
podInitReceiver.returnInitTaskStatus(PodInitActionType.DeactivatePodWizardStep, true, null); podInitReceiver.returnInitTaskStatus(PodInitActionType.DeactivatePodWizardStep, true, null);
this.omnipodUtil.setPodSessionState(null);
return new PumpEnactResult(injector).success(true).enacted(true); return new PumpEnactResult(injector).success(true).enacted(true);
} }
@ -296,19 +219,15 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
} }
return new PumpEnactResult(injector).success(true).enacted(true); return new PumpEnactResult(injector).success(true).enacted(true);
} }
@Override @Override
public PumpEnactResult resetPodStatus() { public PumpEnactResult resetPodStatus() {
delegate.resetPodState(true); getPodStateManager().removeState();
reportImplicitlyCanceledTbr(); reportImplicitlyCanceledTbr();
this.omnipodUtil.setPodSessionState(null);
this.omnipodUtil.removeNextPodAddress();
addSuccessToHistory(System.currentTimeMillis(), PodHistoryEntryType.ResetPodState, null); addSuccessToHistory(System.currentTimeMillis(), PodHistoryEntryType.ResetPodState, null);
return new PumpEnactResult(injector).success(true).enacted(true); return new PumpEnactResult(injector).success(true).enacted(true);
@ -349,11 +268,6 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface
double unitsDelivered = bolusDeliveryResult.getUnitsDelivered(); 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); long pumpId = addSuccessToHistory(bolusStarted.getTime(), PodHistoryEntryType.SetBolus, unitsDelivered + ";" + detailedBolusInfo.carbs);
detailedBolusInfo.date = bolusStarted.getTime(); detailedBolusInfo.date = bolusStarted.getTime();
@ -363,8 +277,8 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface
activePlugin.getActiveTreatments().addToHistoryTreatment(detailedBolusInfo, false); activePlugin.getActiveTreatments().addToHistoryTreatment(detailedBolusInfo, false);
if (delegate.getPodState().hasFaultEvent()) { if (podStateManager.hasFaultEvent()) {
showPodFaultErrorDialog(delegate.getPodState().getFaultEvent().getFaultEventCode(), R.raw.urgentalarm); showPodFaultErrorDialog(podStateManager.getFaultEvent().getFaultEventCode(), R.raw.urgentalarm);
} }
return new PumpEnactResult(injector).success(true).enacted(true).bolusDelivered(unitsDelivered); return new PumpEnactResult(injector).success(true).enacted(true).bolusDelivered(unitsDelivered);
@ -460,12 +374,6 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface
return new PumpEnactResult(injector).success(true).enacted(true); return new PumpEnactResult(injector).success(true).enacted(true);
} }
@Override
public void setPumpStatus(OmnipodPumpStatus pumpStatus) {
this.pumpStatus = pumpStatus;
updatePumpStatus(delegate.getPodState());
}
// TODO should we add this to the OmnipodCommunicationManager interface? // TODO should we add this to the OmnipodCommunicationManager interface?
public PumpEnactResult getPodInfo(PodInfoType podInfoType) { public PumpEnactResult getPodInfo(PodInfoType podInfoType) {
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
@ -547,10 +455,6 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface
return delegate.isReadyForDelivery(); return delegate.isReadyForDelivery();
} }
public String getPodStateAsString() {
return delegate.getPodStateAsString();
}
private void reportImplicitlyCanceledTbr() { private void reportImplicitlyCanceledTbr() {
//TreatmentsPlugin plugin = TreatmentsPlugin.getPlugin(); //TreatmentsPlugin plugin = TreatmentsPlugin.getPlugin();
TreatmentsInterface plugin = activePlugin.getActiveTreatments(); TreatmentsInterface plugin = activePlugin.getActiveTreatments();
@ -598,20 +502,6 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface
return podHistory.getPumpId(); 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) { private void handleSetupActionResult(PodInitActionType podInitActionType, PodInitReceiver podInitReceiver, SetupActionResult res, long time, Profile profile) {
String comment = null; String comment = null;
switch (res.getResultType()) { switch (res.getResultType()) {
@ -725,28 +615,6 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface
sendEvent(new EventNewNotification(notification)); 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() { private boolean isBolusBeepsEnabled() {
return this.pumpStatus.beepBolusEnabled; return this.pumpStatus.beepBolusEnabled;
} }

View file

@ -0,0 +1,178 @@
package info.nightscout.androidaps.plugins.pump.omnipod.driver.comm;
import android.text.TextUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
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;
import info.nightscout.androidaps.logging.AAPSLogger;
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.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.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 OmnipodPumpStatus omnipodPumpStatus;
private final RxBusWrapper rxBus;
private final ResourceHelper resourceHelper;
@Inject
public AapsPodStateManager(AAPSLogger aapsLogger, SP sp, OmnipodPumpStatus omnipodPumpStatus,
RxBusWrapper rxBus, ResourceHelper resourceHelper) {
super(aapsLogger);
if (aapsLogger == null) {
throw new IllegalArgumentException("aapsLogger can not be null");
}
if (sp == null) {
throw new IllegalArgumentException("sp 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");
}
this.aapsLogger = aapsLogger;
this.sp = sp;
this.omnipodPumpStatus = omnipodPumpStatus;
this.rxBus = rxBus;
this.resourceHelper = resourceHelper;
}
@Override
protected String readPodState() {
return sp.getString(OmnipodConst.Prefs.PodState, "");
}
@Override
protected void storePodState(String podState) {
sp.putString(OmnipodConst.Prefs.PodState, podState);
}
@Override
protected void notifyPodStateChanged() {
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<String> alerts = getTranslatedActiveAlerts();
String alertsText = 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());
}
}
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());
if (isSuspended() != PumpStatusType.Suspended.equals(omnipodPumpStatus.pumpStatusType)) {
sendEvent(new EventRefreshOverview("Omnipod Pump", false));
}
}
}
rxBus.send(new EventOmnipodDeviceStatusChange(this));
}
private List<String> getTranslatedActiveAlerts() {
List<String> translatedAlerts = new ArrayList<>();
AlertSet activeAlerts = getActiveAlerts();
for (AlertSlot alertSlot : activeAlerts.getAlertSlots()) {
translatedAlerts.add(translateAlertType(getConfiguredAlertType(alertSlot)));
}
return translatedAlerts;
}
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 String getStringResource(int id, Object... args) {
return resourceHelper.gs(id, args);
}
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);
}
}

View file

@ -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.medtronic.defs.PumpDeviceState
import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodCommandType 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.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 * Created by andy on 4.8.2019
@ -15,7 +15,7 @@ class EventOmnipodDeviceStatusChange : Event {
var rileyLinkServiceState: RileyLinkServiceState? = null var rileyLinkServiceState: RileyLinkServiceState? = null
var rileyLinkError: RileyLinkError? = null var rileyLinkError: RileyLinkError? = null
var podSessionState: PodSessionState? = null var podStateManager: PodStateManager? = null
var errorDescription: String? = null var errorDescription: String? = null
var podDeviceState: PodDeviceState? = null var podDeviceState: PodDeviceState? = null
var pumpDeviceState: PumpDeviceState? = null var pumpDeviceState: PumpDeviceState? = null
@ -32,8 +32,8 @@ class EventOmnipodDeviceStatusChange : Event {
} }
constructor(podSessionState: PodSessionState?) { constructor(podStateManager: PodStateManager?) {
this.podSessionState = podSessionState this.podStateManager = podStateManager
} }
constructor(errorDescription: String?) { constructor(errorDescription: String?) {
@ -58,7 +58,7 @@ class EventOmnipodDeviceStatusChange : Event {
return ("EventOmnipodDeviceStatusChange [" // return ("EventOmnipodDeviceStatusChange [" //
+ "rileyLinkServiceState=" + rileyLinkServiceState + "rileyLinkServiceState=" + rileyLinkServiceState
+ ", rileyLinkError=" + rileyLinkError // + ", rileyLinkError=" + rileyLinkError //
+ ", podSessionState=" + podSessionState // + ", podStateManager=" + podStateManager //
+ ", podDeviceState=" + podDeviceState + "]") + ", podDeviceState=" + podDeviceState + "]")
} }
} }

View file

@ -7,6 +7,8 @@ import android.os.IBinder;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.time.LocalDateTime;
import javax.inject.Inject; import javax.inject.Inject;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
@ -23,11 +25,12 @@ 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.medtronic.defs.PumpDeviceState;
import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodPumpPlugin; import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodPumpPlugin;
import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; 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.OmnipodPumpStatus;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.comm.AapsOmnipodManager; import info.nightscout.androidaps.plugins.pump.omnipod.driver.comm.AapsOmnipodManager;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.ui.OmnipodUIComm; 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.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.OmnipodConst;
import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil; import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil;
@ -42,6 +45,7 @@ public class RileyLinkOmnipodService extends RileyLinkService {
@Inject OmnipodPumpStatus omnipodPumpStatus; @Inject OmnipodPumpStatus omnipodPumpStatus;
@Inject OmnipodUtil omnipodUtil; @Inject OmnipodUtil omnipodUtil;
@Inject OmnipodUIPostprocessor omnipodUIPostprocessor; @Inject OmnipodUIPostprocessor omnipodUIPostprocessor;
@Inject PodStateManager podStateManager;
private static RileyLinkOmnipodService instance; private static RileyLinkOmnipodService instance;
@ -59,12 +63,10 @@ public class RileyLinkOmnipodService extends RileyLinkService {
instance = this; instance = this;
} }
public static RileyLinkOmnipodService getInstance() { public static RileyLinkOmnipodService getInstance() {
return instance; return instance;
} }
@Override @Override
public void onConfigurationChanged(Configuration newConfig) { public void onConfigurationChanged(Configuration newConfig) {
aapsLogger.warn(LTag.PUMPCOMM, "onConfigurationChanged"); aapsLogger.warn(LTag.PUMPCOMM, "onConfigurationChanged");
@ -106,20 +108,20 @@ public class RileyLinkOmnipodService extends RileyLinkService {
} }
private void initializeErosOmnipodManager() { private void initializeErosOmnipodManager() {
if (AapsOmnipodManager.getInstance() == null) { AapsOmnipodManager instance = AapsOmnipodManager.getInstance();
PodSessionState podState = omnipodUtil.loadSessionState(); if (instance == null) {
OmnipodCommunicationManager omnipodCommunicationService = new OmnipodCommunicationManager(injector, rfspy); OmnipodCommunicationManager omnipodCommunicationService = new OmnipodCommunicationManager(injector, rfspy);
//omnipodCommunicationService.setPumpStatus(omnipodPumpStatus);
this.omnipodCommunicationManager = omnipodCommunicationService; this.omnipodCommunicationManager = omnipodCommunicationService;
this.aapsOmnipodManager = new AapsOmnipodManager(omnipodCommunicationService, podState, omnipodPumpStatus, aapsOmnipodManager = new AapsOmnipodManager(omnipodCommunicationService, podStateManager, omnipodPumpStatus,
omnipodUtil, aapsLogger, rxBus, sp, resourceHelper, injector, activePlugin); omnipodUtil, aapsLogger, rxBus, sp, resourceHelper, injector, activePlugin);
omnipodUIComm = new OmnipodUIComm(injector, aapsLogger, omnipodUtil, omnipodUIPostprocessor, aapsOmnipodManager); omnipodUIComm = new OmnipodUIComm(injector, aapsLogger, omnipodUtil, omnipodUIPostprocessor, aapsOmnipodManager);
} else { } else {
aapsOmnipodManager = AapsOmnipodManager.getInstance(); aapsOmnipodManager = instance;
} }
rxBus.send(new EventOmnipodDeviceStatusChange(podStateManager));
} }

View file

@ -14,7 +14,6 @@ public class OmnipodConst {
public class Prefs { public class Prefs {
public static final String PodState = Prefix + "pod_state"; 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 BeepBasalEnabled = R.string.key_omnipod_beep_basal_enabled;
public static final int BeepBolusEnabled = R.string.key_omnipod_beep_bolus_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; public static final int BeepSMBEnabled = R.string.key_omnipod_beep_smb_enabled;
@ -45,6 +44,7 @@ public class OmnipodConst {
public static final int DEFAULT_ADDRESS = 0xffffffff; public static final int DEFAULT_ADDRESS = 0xffffffff;
public static final Duration AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION = Duration.millis(1500); 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 SERVICE_DURATION = Duration.standardHours(80);
public static final Duration EXPIRATION_ADVISORY_WINDOW = Duration.standardHours(9); public static final Duration EXPIRATION_ADVISORY_WINDOW = Duration.standardHours(9);

View file

@ -8,7 +8,6 @@ import com.google.gson.JsonDeserializer;
import com.google.gson.JsonPrimitive; import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializer; import com.google.gson.JsonSerializer;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.joda.time.DateTimeZone; import org.joda.time.DateTimeZone;
import org.joda.time.format.ISODateTimeFormat; import org.joda.time.format.ISODateTimeFormat;
@ -16,21 +15,18 @@ import org.joda.time.format.ISODateTimeFormat;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.interfaces.ActivePluginProvider; import info.nightscout.androidaps.interfaces.ActivePluginProvider;
import info.nightscout.androidaps.logging.AAPSLogger; import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper; import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; 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.RileyLinkUtil;
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.data.RLHistoryItem; 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.OmnipodCommandType;
import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodPodType; 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.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.OmnipodDriverState;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus; import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus;
import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodDeviceStatusChange; import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodDeviceStatusChange;
@ -49,26 +45,22 @@ public class OmnipodUtil {
private final OmnipodPumpStatus omnipodPumpStatus; private final OmnipodPumpStatus omnipodPumpStatus;
private final ActivePluginProvider activePlugins; private final ActivePluginProvider activePlugins;
private final SP sp; private final SP sp;
private final HasAndroidInjector injector;
private boolean lowLevelDebug = true; private boolean lowLevelDebug = true;
private OmnipodCommandType currentCommand; private OmnipodCommandType currentCommand;
private Gson gsonInstance = createGson(); private Gson gsonInstance = createGson();
//private static PodSessionState podSessionState;
//private static PodDeviceState podDeviceState;
private OmnipodPodType omnipodPodType; private OmnipodPodType omnipodPodType;
private OmnipodDriverState driverState = OmnipodDriverState.NotInitalized; private OmnipodDriverState driverState = OmnipodDriverState.NotInitalized;
@Inject @Inject
public OmnipodUtil( public OmnipodUtil(
AAPSLogger aapsLogger, AAPSLogger aapsLogger,
RxBusWrapper rxBus, RxBusWrapper rxBus,
RileyLinkUtil rileyLinkUtil, RileyLinkUtil rileyLinkUtil,
OmnipodPumpStatus omnipodPumpStatus, OmnipodPumpStatus omnipodPumpStatus,
PodStateManager podStateManager,
SP sp, SP sp,
ActivePluginProvider activePlugins, ActivePluginProvider activePlugins
HasAndroidInjector injector
) { ) {
this.aapsLogger = aapsLogger; this.aapsLogger = aapsLogger;
this.rxBus = rxBus; this.rxBus = rxBus;
@ -76,25 +68,20 @@ public class OmnipodUtil {
this.omnipodPumpStatus = omnipodPumpStatus; this.omnipodPumpStatus = omnipodPumpStatus;
this.sp = sp; this.sp = sp;
this.activePlugins = activePlugins; this.activePlugins = activePlugins;
this.injector = injector;
} }
public boolean isLowLevelDebug() { public boolean isLowLevelDebug() {
return lowLevelDebug; return lowLevelDebug;
} }
public void setLowLevelDebug(boolean lowLevelDebug) { public void setLowLevelDebug(boolean lowLevelDebug) {
this.lowLevelDebug = lowLevelDebug; this.lowLevelDebug = lowLevelDebug;
} }
public OmnipodCommandType getCurrentCommand() { public OmnipodCommandType getCurrentCommand() {
return currentCommand; return currentCommand;
} }
public void setCurrentCommand(OmnipodCommandType currentCommand) { public void setCurrentCommand(OmnipodCommandType currentCommand) {
this.currentCommand = currentCommand; this.currentCommand = currentCommand;
@ -109,12 +96,10 @@ public class OmnipodUtil {
MainApp.gs(R.string.omnipod_error_operation_not_possible_no_configuration), (Runnable) null); MainApp.gs(R.string.omnipod_error_operation_not_possible_no_configuration), (Runnable) null);
} }
public OmnipodDriverState getDriverState() { public OmnipodDriverState getDriverState() {
return driverState; return driverState;
} }
public void setDriverState(OmnipodDriverState state) { public void setDriverState(OmnipodDriverState state) {
if (driverState == state) if (driverState == state)
return; return;
@ -132,7 +117,6 @@ public class OmnipodUtil {
// } // }
} }
private Gson createGson() { private Gson createGson() {
GsonBuilder gsonBuilder = new GsonBuilder() GsonBuilder gsonBuilder = new GsonBuilder()
.registerTypeAdapter(DateTime.class, (JsonSerializer<DateTime>) (dateTime, typeOfSrc, context) -> .registerTypeAdapter(DateTime.class, (JsonSerializer<DateTime>) (dateTime, typeOfSrc, context) ->
@ -147,10 +131,8 @@ public class OmnipodUtil {
return gsonBuilder.create(); return gsonBuilder.create();
} }
public void notifyDeviceStatusChanged() {
public void setPodSessionState(PodSessionState podSessionState) {
omnipodPumpStatus.podSessionState = podSessionState;
rxBus.send(new EventOmnipodDeviceStatusChange(podSessionState));
} }
@ -158,37 +140,26 @@ public class OmnipodUtil {
omnipodPumpStatus.podDeviceState = podDeviceState; omnipodPumpStatus.podDeviceState = podDeviceState;
} }
public void setOmnipodPodType(OmnipodPodType omnipodPodType) { public void setOmnipodPodType(OmnipodPodType omnipodPodType) {
this.omnipodPodType = omnipodPodType; this.omnipodPodType = omnipodPodType;
} }
public OmnipodPodType getOmnipodPodType() { public OmnipodPodType getOmnipodPodType() {
return this.omnipodPodType; return this.omnipodPodType;
} }
public PodDeviceState getPodDeviceState() { public PodDeviceState getPodDeviceState() {
return omnipodPumpStatus.podDeviceState; return omnipodPumpStatus.podDeviceState;
} }
public PodSessionState getPodSessionState() {
return omnipodPumpStatus.podSessionState;
}
public boolean isOmnipodEros() { public boolean isOmnipodEros() {
return this.activePlugins.getActivePump().model() == PumpType.Insulet_Omnipod; return this.activePlugins.getActivePump().model() == PumpType.Insulet_Omnipod;
} }
public boolean isOmnipodDash() { public boolean isOmnipodDash() {
return this.activePlugins.getActivePump().model() == PumpType.Insulet_Omnipod_Dash; return this.activePlugins.getActivePump().model() == PumpType.Insulet_Omnipod_Dash;
} }
public void setPumpType(PumpType pumpType_) { public void setPumpType(PumpType pumpType_) {
omnipodPumpStatus.pumpType = pumpType_; omnipodPumpStatus.pumpType = pumpType_;
} }
@ -197,33 +168,10 @@ public class OmnipodUtil {
return omnipodPumpStatus.pumpType; return omnipodPumpStatus.pumpType;
} }
public Gson getGsonInstance() { public Gson getGsonInstance() {
return this.gsonInstance; 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() { public AAPSLogger getAapsLogger() {
return this.aapsLogger; return this.aapsLogger;
} }
@ -231,25 +179,4 @@ public class OmnipodUtil {
public SP getSp() { public SP getSp() {
return this.sp; 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;
}
} }

View file

@ -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.OmnipodCommunicationManagerInterface;
import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInitActionType; 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.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; import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus;
/** /**
@ -34,7 +34,7 @@ public class OmnipodDashCommunicationManager implements OmnipodCommunicationMana
// RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L); // RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L);
} }
private PodSessionState getPodSessionState() { private PodStateManager getPodStateManager() {
return null; return null;
} }
@ -114,11 +114,6 @@ public class OmnipodDashCommunicationManager implements OmnipodCommunicationMana
return null; return null;
} }
@Override
public void setPumpStatus(OmnipodPumpStatus pumpStatusLocal) {
}
@Override @Override
public PodInfoRecentPulseLog readPulseLog() { public PodInfoRecentPulseLog readPulseLog() {
return null; return null;

View file

@ -26,8 +26,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:orientation="horizontal"
android:paddingBottom="5dp"
android:paddingTop="2dp" android:paddingTop="2dp"
android:paddingBottom="5dp"
android:visibility="gone"> android:visibility="gone">
<TextView <TextView
@ -45,10 +45,10 @@
<View <View
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="2dip" android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp" android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="5dp"
android:background="@color/listdelimiter" /> android:background="@color/listdelimiter" />
<LinearLayout <LinearLayout
@ -70,8 +70,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0" android:layout_weight="0"
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp" android:paddingStart="2dp"
android:paddingEnd="2dp"
android:text=":" android:text=":"
android:textSize="14sp" /> android:textSize="14sp" />
@ -93,10 +93,10 @@
<View <View
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="2dip" android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp" android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="5dp"
android:background="@color/listdelimiter" /> android:background="@color/listdelimiter" />
<!-- Pod Address --> <!-- Pod Address -->
@ -119,8 +119,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0" android:layout_weight="0"
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp" android:paddingStart="2dp"
android:paddingEnd="2dp"
android:text=":" android:text=":"
android:textSize="14sp" /> android:textSize="14sp" />
@ -133,12 +133,118 @@
android:paddingLeft="5dp" android:paddingLeft="5dp"
android:textColor="@android:color/white" android:textColor="@android:color/white"
android:textSize="14sp" /> android:textSize="14sp" />
</LinearLayout>
<!-- Pod Lot -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:gravity="end"
android:paddingRight="5dp"
android:text="@string/omnipod_pod_lot"
android:textSize="14sp" />
<TextView
android:layout_width="5dp"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center_horizontal"
android:paddingStart="2dp"
android:paddingEnd="2dp"
android:text=":"
android:textSize="14sp" />
<TextView
android:id="@+id/omnipod_pod_lot"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:paddingLeft="5dp"
android:textColor="@android:color/white"
android:textSize="14sp" />
</LinearLayout>
<!-- Pod Tid -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:gravity="end"
android:paddingRight="5dp"
android:text="@string/omnipod_pod_tid"
android:textSize="14sp" />
<TextView
android:layout_width="5dp"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center_horizontal"
android:paddingStart="2dp"
android:paddingEnd="2dp"
android:text=":"
android:textSize="14sp" />
<TextView
android:id="@+id/omnipod_pod_tid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:paddingLeft="5dp"
android:textColor="@android:color/white"
android:textSize="14sp" />
</LinearLayout>
<!-- Pod fw version -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:gravity="end"
android:paddingRight="5dp"
android:text="@string/omnipod_pod_fw_version"
android:textSize="14sp" />
<TextView
android:layout_width="5dp"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center_horizontal"
android:paddingStart="2dp"
android:paddingEnd="2dp"
android:text=":"
android:textSize="14sp" />
<TextView
android:id="@+id/omnipod_pod_fw_version"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:paddingLeft="5dp"
android:textColor="@android:color/white"
android:textSize="14sp" />
</LinearLayout> </LinearLayout>
<!-- Pod Address --> <!-- Pod Expires -->
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -158,8 +264,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0" android:layout_weight="0"
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp" android:paddingStart="2dp"
android:paddingEnd="2dp"
android:text=":" android:text=":"
android:textSize="14sp" /> android:textSize="14sp" />
@ -175,7 +281,7 @@
</LinearLayout> </LinearLayout>
<!-- Pod Status -->
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -195,8 +301,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0" android:layout_weight="0"
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp" android:paddingStart="2dp"
android:paddingEnd="2dp"
android:text=":" android:text=":"
android:textSize="14sp" /> android:textSize="14sp" />
@ -212,7 +318,6 @@
android:textColor="@android:color/white" android:textColor="@android:color/white"
android:textSize="14sp" /> android:textSize="14sp" />
</LinearLayout> </LinearLayout>
<TextView <TextView
@ -225,10 +330,10 @@
<View <View
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="2dip" android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp" android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="5dp"
android:background="@color/listdelimiter" /> android:background="@color/listdelimiter" />
<LinearLayout <LinearLayout
@ -250,8 +355,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0" android:layout_weight="0"
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp" android:paddingStart="2dp"
android:paddingEnd="2dp"
android:text=":" android:text=":"
android:textSize="14sp" /> android:textSize="14sp" />
@ -270,10 +375,10 @@
<View <View
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="2dip" android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp" android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="5dp"
android:background="@color/listdelimiter" /> android:background="@color/listdelimiter" />
<LinearLayout <LinearLayout
@ -295,8 +400,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0" android:layout_weight="0"
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp" android:paddingStart="2dp"
android:paddingEnd="2dp"
android:text=":" android:text=":"
android:textSize="14sp" /> android:textSize="14sp" />
@ -316,10 +421,10 @@
<View <View
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="2dip" android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp" android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="5dp"
android:background="@color/listdelimiter" /> android:background="@color/listdelimiter" />
<LinearLayout <LinearLayout
@ -341,8 +446,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0" android:layout_weight="0"
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp" android:paddingStart="2dp"
android:paddingEnd="2dp"
android:text=":" android:text=":"
android:textSize="14sp" /> android:textSize="14sp" />
@ -361,10 +466,10 @@
<View <View
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="2dip" android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp" android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="5dp"
android:background="@color/listdelimiter" /> android:background="@color/listdelimiter" />
<LinearLayout <LinearLayout
@ -386,8 +491,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0" android:layout_weight="0"
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp" android:paddingStart="2dp"
android:paddingEnd="2dp"
android:text=":" android:text=":"
android:textSize="14sp" /> android:textSize="14sp" />
@ -406,10 +511,10 @@
<View <View
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="2dip" android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp" android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="5dp"
android:background="@color/listdelimiter" /> android:background="@color/listdelimiter" />
@ -432,8 +537,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0" android:layout_weight="0"
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp" android:paddingStart="2dp"
android:paddingEnd="2dp"
android:text=":" android:text=":"
android:textSize="14sp" /> android:textSize="14sp" />
@ -453,10 +558,10 @@
<View <View
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="2dip" android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp" android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="5dp"
android:background="@color/listdelimiter" /> android:background="@color/listdelimiter" />
<LinearLayout <LinearLayout
@ -478,8 +583,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0" android:layout_weight="0"
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp" android:paddingStart="2dp"
android:paddingEnd="2dp"
android:text=":" android:text=":"
android:textSize="14sp" /> android:textSize="14sp" />
@ -498,10 +603,10 @@
<View <View
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="2dip" android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp" android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="5dp"
android:background="@color/listdelimiter" /> android:background="@color/listdelimiter" />
<LinearLayout <LinearLayout
@ -523,8 +628,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0" android:layout_weight="0"
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp" android:paddingStart="2dp"
android:paddingEnd="2dp"
android:text=":" android:text=":"
android:textSize="14sp" /> android:textSize="14sp" />
@ -543,10 +648,10 @@
<View <View
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="2dip" android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp" android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="5dp"
android:background="@color/listdelimiter" /> android:background="@color/listdelimiter" />
@ -621,8 +726,7 @@
android:drawableTop="@drawable/icon_cp_bolus_correction" android:drawableTop="@drawable/icon_cp_bolus_correction"
android:paddingLeft="0dp" android:paddingLeft="0dp"
android:paddingRight="0dp" android:paddingRight="0dp"
android:text="@string/omnipod_read_pulse_log_short" android:text="@string/omnipod_read_pulse_log_short" />
/>
</LinearLayout> </LinearLayout>

View file

@ -1863,9 +1863,11 @@
<string name="omnipod_reservoir_over50">Over 50 U</string> <string name="omnipod_reservoir_over50">Over 50 U</string>
<string name="omnipod_pod_address">Pod Address</string> <string name="omnipod_pod_address">Pod Address</string>
<string name="omnipod_pod_expiry">Pod Expires</string> <string name="omnipod_pod_expiry">Pod Expires</string>
<string name="omnipod_pod_name_no_info">No info</string> <string name="omnipod_pod_status_no_pod_connected">No Pod connected</string>
<string name="omnipod_pod_no_pod_connected">No Pod connected</string> <string name="omnipod_pod_setup_in_progress">Pod setup in progress</string>
<string name="omnipod_pod_not_initalized">Not initialized</string> <string name="omnipod_pod_status_not_initalized">Pod not initialized</string>
<string name="omnipod_pod_status_pod_fault">!!! Pod Fault</string>
<string name="omnipod_pod_status_pod_running">Pod running</string>
<string name="omnipod_pod_active_alerts">Active Pod Alerts</string> <string name="omnipod_pod_active_alerts">Active Pod Alerts</string>
<string name="omnipod_ack_short">Ack Alerts</string> <string name="omnipod_ack_short">Ack Alerts</string>
<string name="omnipod_last_bolus" translatable="false">%1$.2f %2$s (%3$s)</string> <string name="omnipod_last_bolus" translatable="false">%1$.2f %2$s (%3$s)</string>
@ -1982,5 +1984,8 @@
<string name="omnipod_bolus_failed_uncertain">Unable to verify whether the bolus succeeded. Please verify that your Pod is bolusing or cancel the bolus.</string> <string name="omnipod_bolus_failed_uncertain">Unable to verify whether the bolus succeeded. Please verify that your Pod is bolusing or cancel the bolus.</string>
<string name="omnipod_rl_stats">RL Stats</string> <string name="omnipod_rl_stats">RL Stats</string>
<string name="omnipod_read_pulse_log_short">Pulse Log</string> <string name="omnipod_read_pulse_log_short">Pulse Log</string>
<string name="omnipod_pod_lot">LOT</string>
<string name="omnipod_pod_tid">TID</string>
<string name="omnipod_pod_fw_version">PM / PI version</string>
</resources> </resources>

View file

@ -0,0 +1,100 @@
package info.nightscout.androidaps.plugins.pump.omnipod.defs.state;
import org.joda.time.DateTime;
import org.joda.time.DateTimeUtils;
import org.joda.time.DateTimeZone;
import org.joda.time.Duration;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.powermock.modules.junit4.PowerMockRunner;
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 AAPSLogger aapsLogger;
@Mock SP sp;
@Mock OmnipodPumpStatus omnipodPumpStatus;
RxBusWrapper rxBus = new RxBusWrapper();
@Mock ResourceHelper resourceHelper;
@Test
public void times() {
DateTimeZone timeZone = DateTimeZone.UTC;
DateTimeZone.setDefault(timeZone);
DateTime now = new DateTime(2020, 1, 1, 1, 2, 3, timeZone);
DateTimeUtils.setCurrentMillisFixed(now.getMillis());
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);
assertEquals(now, podStateManager.getTime());
assertEquals(Duration.standardHours(1).plus(Duration.standardMinutes(2).plus(Duration.standardSeconds(3))), podStateManager.getScheduleOffset());
}
@Test
public void changeSystemTimeZoneWithoutChangingPodTimeZone() {
DateTimeZone timeZone = DateTimeZone.UTC;
DateTimeZone.setDefault(timeZone);
DateTime now = new DateTime(2020, 1, 1, 1, 2, 3, timeZone);
DateTimeUtils.setCurrentMillisFixed(now.getMillis());
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);
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, podStateManager.getTime());
assertEquals(Duration.standardHours(1).plus(Duration.standardMinutes(2).plus(Duration.standardSeconds(3))), podStateManager.getScheduleOffset());
}
@Test
public void changeSystemTimeZoneAndChangePodTimeZone() {
DateTimeZone timeZone = DateTimeZone.UTC;
DateTimeZone.setDefault(timeZone);
DateTime now = new DateTime(2020, 1, 1, 1, 2, 3, timeZone);
DateTimeUtils.setCurrentMillisFixed(now.getMillis());
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);
DateTimeZone newTimeZone = DateTimeZone.forOffsetHours(2);
DateTimeZone.setDefault(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), podStateManager.getTime());
assertEquals(Duration.standardHours(3).plus(Duration.standardMinutes(2).plus(Duration.standardSeconds(3))), podStateManager.getScheduleOffset());
}
@After
public void tearDown() {
DateTimeUtils.setCurrentMillisSystem();
}
}

View file

@ -1,95 +0,0 @@
package info.nightscout.androidaps.plugins.pump.omnipod.defs.state;
import org.joda.time.DateTime;
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.mockito.Mock;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.plugins.pump.omnipod.defs.FirmwareVersion;
import static org.junit.Assert.assertEquals;
public class PodSessionStateTest {
@Mock HasAndroidInjector hasAndroidInjector;
@Test
@Ignore("Not Dagger compliant") // FIXME
public void times() {
DateTimeZone timeZone = DateTimeZone.UTC;
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);
assertEquals(now, podSessionState.getTime());
assertEquals(Duration.standardHours(1).plus(Duration.standardMinutes(2).plus(Duration.standardSeconds(3))), podSessionState.getScheduleOffset());
}
@Test
@Ignore("Not Dagger compliant") // FIXME
public void changeSystemTimeZoneWithoutChangingPodTimeZone() {
DateTimeZone timeZone = DateTimeZone.UTC;
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);
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());
}
@Test
@Ignore("Not Dagger compliant") // FIXME
public void changeSystemTimeZoneAndChangePodTimeZone() {
DateTimeZone timeZone = DateTimeZone.UTC;
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);
DateTimeZone newTimeZone = DateTimeZone.forOffsetHours(2);
DateTimeZone.setDefault(newTimeZone);
podSessionState.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());
}
@After
public void tearDown() {
DateTimeUtils.setCurrentMillisSystem();
}
}