Merge pull request #77 from AAPS-Omnipod/omnipod_eros_dev_upstream_merge

Latest Omnipod updates
This commit is contained in:
Milos Kozak 2020-11-23 13:27:13 +01:00 committed by GitHub
commit 9c766ff5a8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
48 changed files with 741 additions and 239 deletions

View file

@ -7,6 +7,7 @@ import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.plugins.general.nsclient.UploadQueue
import info.nightscout.androidaps.plugins.treatments.TreatmentService
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.DateUtil
@ -27,8 +28,10 @@ class TreatmentsPluginHistory @Inject constructor(
profileFunction: ProfileFunction,
activePlugin: ActivePluginProvider,
nsUpload: NSUpload,
fabricPrivacy: FabricPrivacy, dateUtil: DateUtil
) : TreatmentsPlugin(injector, aapsLogger, rxBus, resourceHelper, context, sp, profileFunction, activePlugin, nsUpload, fabricPrivacy, dateUtil) {
fabricPrivacy: FabricPrivacy,
dateUtil: DateUtil,
uploadQueue: UploadQueue
) : TreatmentsPlugin(injector, aapsLogger, rxBus, resourceHelper, context, sp, profileFunction, activePlugin, nsUpload, fabricPrivacy, dateUtil, uploadQueue) {
init {
onStart()

View file

@ -30,13 +30,12 @@ import info.nightscout.androidaps.data.NonOverlappingIntervals;
import info.nightscout.androidaps.data.OverlappingIntervals;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.ProfileIntervals;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.interfaces.ProfileStore;
import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.ProfileSwitch;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.EventReloadProfileSwitchData;
import info.nightscout.androidaps.events.EventReloadTempBasalData;
import info.nightscout.androidaps.events.EventReloadTreatmentData;
@ -45,13 +44,15 @@ import info.nightscout.androidaps.interfaces.ActivePluginProvider;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PluginDescription;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.interfaces.ProfileFunction;
import info.nightscout.androidaps.interfaces.ProfileStore;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
import info.nightscout.androidaps.logging.AAPSLogger;
import info.nightscout.androidaps.logging.LTag;
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
import info.nightscout.androidaps.interfaces.ProfileFunction;
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
import info.nightscout.androidaps.plugins.general.nsclient.UploadQueue;
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification;
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult;
@ -75,6 +76,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
private final ProfileFunction profileFunction;
private final ActivePluginProvider activePlugin;
private final NSUpload nsUpload;
private final UploadQueue uploadQueue;
private final FabricPrivacy fabricPrivacy;
private final DateUtil dateUtil;
@ -103,7 +105,8 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
ActivePluginProvider activePlugin,
NSUpload nsUpload,
FabricPrivacy fabricPrivacy,
DateUtil dateUtil
DateUtil dateUtil,
UploadQueue uploadQueue
) {
super(new PluginDescription()
.mainType(PluginType.TREATMENT)
@ -124,6 +127,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
this.fabricPrivacy = fabricPrivacy;
this.dateUtil = dateUtil;
this.nsUpload = nsUpload;
this.uploadQueue = uploadQueue;
}
@Override
@ -338,8 +342,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
if (last == null) {
getAapsLogger().debug(LTag.DATATREATMENTS, "Last bolus time: NOTHING FOUND");
return 0;
}
else {
} else {
getAapsLogger().debug(LTag.DATATREATMENTS, "Last bolus time: " + dateUtil.dateAndTimeString(last.date));
return last.date;
}
@ -350,8 +353,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
if (last == null) {
getAapsLogger().debug(LTag.DATATREATMENTS, "Last manual bolus time: NOTHING FOUND");
return 0;
}
else {
} else {
getAapsLogger().debug(LTag.DATATREATMENTS, "Last manual bolus time: " + dateUtil.dateAndTimeString(last.date));
return last.date;
}
@ -362,8 +364,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
if (last == null) {
getAapsLogger().debug(LTag.DATATREATMENTS, "Last Carb time: NOTHING FOUND");
return 0;
}
else {
} else {
getAapsLogger().debug(LTag.DATATREATMENTS, "Last Carb time: " + dateUtil.dateAndTimeString(last.date));
return last.date;
}
@ -387,6 +388,16 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
return getTempBasalFromHistory(System.currentTimeMillis()) != null;
}
@Override public void removeTempBasal(TemporaryBasal tempBasal) {
String tempBasalId = tempBasal._id;
if (NSUpload.isIdValid(tempBasalId)) {
nsUpload.removeCareportalEntryFromNS(tempBasalId);
} else {
uploadQueue.removeID("dbAdd", tempBasalId);
}
MainApp.getDbHelper().delete(tempBasal);
}
@Override
public boolean isInHistoryExtendedBoluslInProgress() {
return getExtendedBolusFromHistory(System.currentTimeMillis()) != null; //TODO: crosscheck here

View file

@ -11,7 +11,6 @@ import androidx.cardview.widget.CardView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import dagger.android.support.DaggerFragment
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Intervals
import info.nightscout.androidaps.data.IobTotal
@ -19,33 +18,29 @@ import info.nightscout.androidaps.db.Source
import info.nightscout.androidaps.db.TemporaryBasal
import info.nightscout.androidaps.events.EventTempBasalChange
import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.plugins.general.nsclient.UploadQueue
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished
import info.nightscout.androidaps.plugins.treatments.fragments.TreatmentsTemporaryBasalsFragment.RecyclerViewAdapter.TempBasalsViewHolder
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.alertDialogs.OKDialog.showConfirmation
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.treatments_tempbasals_fragment.*
import javax.inject.Inject
class TreatmentsTemporaryBasalsFragment : DaggerFragment() {
private val disposable = CompositeDisposable()
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var sp: SP
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var activePlugin: ActivePluginProvider
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var nsUpload: NSUpload
@Inject lateinit var uploadQueue: UploadQueue
@Inject lateinit var dateUtil: DateUtil
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
@ -81,6 +76,7 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() {
}
inner class RecyclerViewAdapter internal constructor(private var tempBasalList: Intervals<TemporaryBasal>) : RecyclerView.Adapter<TempBasalsViewHolder>() {
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): TempBasalsViewHolder {
val v = LayoutInflater.from(viewGroup.context).inflate(R.layout.treatments_tempbasals_item, viewGroup, false)
return TempBasalsViewHolder(v)
@ -142,6 +138,7 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() {
}
inner class TempBasalsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var cv: CardView = itemView.findViewById(R.id.tempbasals_cardview)
var date: TextView = itemView.findViewById(R.id.tempbasals_date)
var duration: TextView = itemView.findViewById(R.id.tempbasals_duration)
@ -166,10 +163,7 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() {
${resourceHelper.gs(R.string.date)}: ${dateUtil.dateAndTimeString(tempBasal.date)}
""".trimIndent(),
DialogInterface.OnClickListener { _: DialogInterface?, _: Int ->
val id = tempBasal._id
if (NSUpload.isIdValid(id)) nsUpload.removeCareportalEntryFromNS(id)
else uploadQueue.removeID("dbAdd", id)
MainApp.getDbHelper().delete(tempBasal)
activePlugin.activeTreatments.removeTempBasal(tempBasal)
}, null)
}
}

View file

@ -7,11 +7,12 @@ import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.db.TDD
import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.plugins.general.nsclient.UploadQueue
import info.nightscout.androidaps.plugins.treatments.TreatmentService
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.DateUtil
@ -34,8 +35,9 @@ class TddCalculator @Inject constructor(
val profileFunction: ProfileFunction,
fabricPrivacy: FabricPrivacy,
nsUpload: NSUpload,
private val dateUtil: DateUtil
) : TreatmentsPlugin(injector, aapsLogger, rxBus, resourceHelper, mainApp, sp, profileFunction, activePlugin, nsUpload, fabricPrivacy, dateUtil) {
private val dateUtil: DateUtil,
uploadQueue: UploadQueue
) : TreatmentsPlugin(injector, aapsLogger, rxBus, resourceHelper, mainApp, sp, profileFunction, activePlugin, nsUpload, fabricPrivacy, dateUtil, uploadQueue) {
init {
service = TreatmentService(injector) // plugin is not started

View file

@ -8,6 +8,7 @@ import info.nightscout.androidaps.TestBaseWithProfile
import info.nightscout.androidaps.db.DatabaseHelper
import info.nightscout.androidaps.db.TemporaryBasal
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.plugins.general.nsclient.UploadQueue
import info.nightscout.androidaps.plugins.insulin.InsulinOrefRapidActingPlugin
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
@ -33,6 +34,7 @@ class TreatmentsPluginTest : TestBaseWithProfile() {
@Mock lateinit var databaseHelper: DatabaseHelper
@Mock lateinit var treatmentService: TreatmentService
@Mock lateinit var nsUpload: NSUpload
@Mock lateinit var uploadQueue: UploadQueue
val injector = HasAndroidInjector {
AndroidInjector {
@ -58,7 +60,7 @@ class TreatmentsPluginTest : TestBaseWithProfile() {
`when`(profileFunction.getProfile(ArgumentMatchers.anyLong())).thenReturn(validProfile)
`when`(activePluginProvider.activeInsulin).thenReturn(insulinOrefRapidActingPlugin)
sot = TreatmentsPlugin(profileInjector, aapsLogger, rxBus, resourceHelper, context, sp, profileFunction, activePluginProvider, nsUpload, fabricPrivacy, dateUtil)
sot = TreatmentsPlugin(profileInjector, aapsLogger, rxBus, resourceHelper, context, sp, profileFunction, activePluginProvider, nsUpload, fabricPrivacy, dateUtil, uploadQueue)
sot.service = treatmentService
}

View file

@ -55,6 +55,8 @@ public interface TreatmentsInterface {
NonOverlappingIntervals<TemporaryBasal> getTemporaryBasalsFromHistory();
void removeTempBasal(TemporaryBasal temporaryBasal);
boolean isInHistoryExtendedBoluslInProgress();
ExtendedBolus getExtendedBolusFromHistory(long time);

View file

@ -33,6 +33,7 @@ import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventAppInitialized;
@ -82,9 +83,11 @@ import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodActiveA
import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodFaultEventChanged;
import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged;
import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodTbrChanged;
import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodUncertainTbrRecovered;
import info.nightscout.androidaps.plugins.pump.omnipod.manager.AapsOmnipodManager;
import info.nightscout.androidaps.plugins.pump.omnipod.queue.command.CommandAcknowledgeAlerts;
import info.nightscout.androidaps.plugins.pump.omnipod.queue.command.CommandHandleTimeChange;
import info.nightscout.androidaps.plugins.pump.omnipod.queue.command.CommandPlayTestBeep;
import info.nightscout.androidaps.plugins.pump.omnipod.queue.command.CommandUpdateAlertConfiguration;
import info.nightscout.androidaps.plugins.pump.omnipod.queue.command.OmnipodCustomCommand;
import info.nightscout.androidaps.plugins.pump.omnipod.queue.command.OmnipodCustomCommandType;
@ -154,6 +157,7 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
private final Handler loopHandler = new Handler(Looper.getMainLooper());
private final Runnable statusChecker;
private boolean isSetTempBasalRunning;
private boolean isCancelTempBasalRunning;
@Inject
@ -285,7 +289,12 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
disposables.add(rxBus
.toObservable(EventOmnipodTbrChanged.class)
.observeOn(Schedulers.io())
.subscribe(event -> updateAapsTbr(), fabricPrivacy::logException)
.subscribe(event -> handleCancelledTbr(), fabricPrivacy::logException)
);
disposables.add(rxBus
.toObservable(EventOmnipodUncertainTbrRecovered.class)
.observeOn(Schedulers.io())
.subscribe(event -> handleUncertainTbrRecovery(), fabricPrivacy::logException)
);
disposables.add(rxBus
.toObservable(EventOmnipodActiveAlertsChanged.class)
@ -307,6 +316,7 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
event.isChanged(getResourceHelper(), R.string.key_omnipod_smb_beeps_enabled) ||
event.isChanged(getResourceHelper(), R.string.key_omnipod_suspend_delivery_button_enabled) ||
event.isChanged(getResourceHelper(), R.string.key_omnipod_pulse_log_button_enabled) ||
event.isChanged(getResourceHelper(), R.string.key_omnipod_rileylink_stats_button_enabled) ||
event.isChanged(getResourceHelper(), R.string.key_omnipod_time_change_event_enabled) ||
event.isChanged(getResourceHelper(), R.string.key_omnipod_notification_uncertain_tbr_sound_enabled) ||
event.isChanged(getResourceHelper(), R.string.key_omnipod_notification_uncertain_smb_sound_enabled) ||
@ -350,17 +360,46 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
return rileyLinkServiceData.rileyLinkServiceState.isReady();
}
private void updateAapsTbr() {
// As per the characteristics of the Omnipod, we only know whether or not a TBR is currently active
// But it doesn't tell us the duration or amount, so we can only update TBR status in AAPS if
// The pod is not running a TBR, while AAPS thinks it is
if (!podStateManager.isTempBasalRunning()) {
// Only report TBR cancellations if they haven't been explicitly requested
if (!isCancelTempBasalRunning) {
if (activePlugin.getActiveTreatments().isTempBasalInProgress() && !aapsOmnipodManager.hasSuspendedFakeTbr()) {
aapsOmnipodManager.reportCancelledTbr();
}
private void handleCancelledTbr() {
// Only report TBR cancellations if they haven't been explicitly requested
if (isCancelTempBasalRunning) {
return;
}
if (!podStateManager.isTempBasalRunning() && activePlugin.getActiveTreatments().isTempBasalInProgress() && !aapsOmnipodManager.hasSuspendedFakeTbr()) {
aapsOmnipodManager.reportCancelledTbr();
}
}
private void handleUncertainTbrRecovery() {
// Ignore changes in certainty during tbr commands; these are normal
if (isSetTempBasalRunning || isCancelTempBasalRunning) {
return;
}
TemporaryBasal tempBasal = activePlugin.getActiveTreatments().getTempBasalFromHistory(System.currentTimeMillis());
if (podStateManager.isTempBasalRunning() && tempBasal == null) {
if (podStateManager.hasTempBasal()) {
aapsLogger.warn(LTag.PUMP, "Registering TBR that AAPS was unaware of");
long pumpId = aapsOmnipodManager.addTbrSuccessToHistory(podStateManager.getTempBasalStartTime().getMillis(),
new TempBasalPair(podStateManager.getTempBasalAmount(), false, (int) podStateManager.getTempBasalDuration().getStandardMinutes()));
TemporaryBasal temporaryBasal = new TemporaryBasal(getInjector()) //
.absolute(podStateManager.getTempBasalAmount()) //
.duration((int) podStateManager.getTempBasalDuration().getStandardMinutes())
.date(podStateManager.getTempBasalStartTime().getMillis()) //
.source(Source.PUMP) //
.pumpId(pumpId);
activePlugin.getActiveTreatments().addToHistoryTempBasal(temporaryBasal);
} else {
// Not sure what's going on. Notify the user
aapsLogger.error(LTag.PUMP, "Unknown TBR in both Pod state and AAPS");
rxBus.send(new EventNewNotification(new Notification(Notification.OMNIPOD_PUMP_ALARM, resourceHelper.gs(R.string.omnipod_error_tbr_running_but_aaps_not_aware), Notification.NORMAL).sound(R.raw.boluserror)));
}
} else if (!podStateManager.isTempBasalRunning() && tempBasal != null) {
aapsLogger.warn(LTag.PUMP, "Removing AAPS TBR that actually hadn't succeeded");
activePlugin.getActiveTreatments().removeTempBasal(tempBasal);
}
}
@ -506,18 +545,26 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
}
/**
* The only actual status requests we send to the Pod here are on startup (in {@link #initializeAfterRileyLinkConnection() initializeAfterRileyLinkConnection()})
* And when the user explicitly requested it by clicking the Refresh button on the Omnipod tab (which is executed through {@link #executeCustomCommand(CustomCommand)})
* We don't do periodical status requests because that could drain the Pod's battery
* The only actual status requests we send to the Pod here are on startup (in {@link #initializeAfterRileyLinkConnection() initializeAfterRileyLinkConnection()})
* And when the basal and/or temp basal status is uncertain
* When the user explicitly requested it by clicking the Refresh button on the Omnipod tab (which is executed through {@link #executeCustomCommand(CustomCommand)})
*/
@Override
public void getPumpStatus() {
if (firstRun) {
initializeAfterRileyLinkConnection();
firstRun = false;
} else if (!podStateManager.isBasalCertain() || !podStateManager.isTempBasalCertain()) {
aapsLogger.info(LTag.PUMP, "Acknowledged AAPS getPumpStatus request because basal and/or temp basal is uncertain");
getPodStatus();
}
}
private PumpEnactResult getPodStatus() {
return executeCommand(OmnipodCommandType.GET_POD_STATUS, aapsOmnipodManager::getPodStatus);
}
@NonNull
@Override
public PumpEnactResult setNewBasalProfile(Profile profile) {
@ -620,7 +667,13 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
}
}
PumpEnactResult result = executeCommand(OmnipodCommandType.SET_TEMPORARY_BASAL, () -> aapsOmnipodManager.setTemporaryBasal(new TempBasalPair(absoluteRate, false, durationInMinutes)));
isSetTempBasalRunning = true;
PumpEnactResult result;
try {
result = executeCommand(OmnipodCommandType.SET_TEMPORARY_BASAL, () -> aapsOmnipodManager.setTemporaryBasal(new TempBasalPair(absoluteRate, false, durationInMinutes)));
} finally {
isSetTempBasalRunning = false;
}
aapsLogger.info(LTag.PUMP, "setTempBasalAbsolute - setTBR. Response: " + result.success);
@ -781,7 +834,7 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
case ACKNOWLEDGE_ALERTS:
return executeCommand(OmnipodCommandType.ACKNOWLEDGE_ALERTS, aapsOmnipodManager::acknowledgeAlerts);
case GET_POD_STATUS:
return executeCommand(OmnipodCommandType.GET_POD_STATUS, aapsOmnipodManager::getPodStatus);
return getPodStatus();
case READ_PULSE_LOG:
return retrievePulseLog();
case SUSPEND_DELIVERY:
@ -794,6 +847,8 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
return handleTimeChange(((CommandHandleTimeChange) command).isRequestedByUser());
case UPDATE_ALERT_CONFIGURATION:
return updateAlertConfiguration();
case PLAY_TEST_BEEP:
return executeCommand(OmnipodCommandType.PLAY_TEST_BEEP, () -> aapsOmnipodManager.playTestBeep(((CommandPlayTestBeep) command).getBeepType()));
default:
aapsLogger.warn(LTag.PUMP, "Unknown custom command: " + commandType);
return new PumpEnactResult(getInjector()).success(false).enacted(false).comment(resourceHelper.gs(R.string.omnipod_error_unknown_custom_command, commandType));
@ -857,7 +912,7 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
} else {
// Even if automatically changing the time is disabled, we still want to at least do a GetStatus request,
// in order to update the Pod's activation time, which we need for calculating the time on the Pod
result = executeCommand(OmnipodCommandType.GET_POD_STATUS, aapsOmnipodManager::getPodStatus);
result = getPodStatus();
}
if (result.success) {
@ -988,15 +1043,19 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
private void initializeAfterRileyLinkConnection() {
if (podStateManager.getActivationProgress().isAtLeast(ActivationProgress.PAIRING_COMPLETED)) {
boolean success = false;
for (int i = 0; STARTUP_STATUS_REQUEST_TRIES > i; i++) {
PumpEnactResult result = executeCommand(OmnipodCommandType.GET_POD_STATUS, aapsOmnipodManager::getPodStatus);
PumpEnactResult result = getPodStatus();
if (result.success) {
success = true;
aapsLogger.debug(LTag.PUMP, "Successfully retrieved Pod status on startup");
break;
} else {
aapsLogger.warn(LTag.PUMP, "Failed to retrieve Pod status on startup");
}
}
if (!success) {
aapsLogger.warn(LTag.PUMP, "Failed to retrieve Pod status on startup");
rxBus.send(new EventNewNotification(new Notification(Notification.OMNIPOD_PUMP_ALARM, resourceHelper.gs(R.string.omnipod_error_failed_to_refresh_status_on_startup), Notification.NORMAL)));
}
} else {
aapsLogger.debug(LTag.PUMP, "Not retrieving Pod status on startup: no Pod running");
}

View file

@ -21,7 +21,8 @@ public enum OmnipodCommandType {
ACKNOWLEDGE_ALERTS(R.string.omnipod_cmd_acknowledge_alerts), //
READ_POD_PULSE_LOG(R.string.omnipod_cmd_read_pulse_log), //
SUSPEND_DELIVERY(R.string.omnipod_cmd_suspend_delivery),
RESUME_DELIVERY(R.string.omnipod_cmd_resume_delivery);
RESUME_DELIVERY(R.string.omnipod_cmd_resume_delivery),
PLAY_TEST_BEEP(R.string.omnipod_cmd_play_test_beep);
private int resourceId;

View file

@ -21,6 +21,7 @@ public class OmnipodStorageKeys {
public static final int NOTIFICATION_UNCERTAIN_SMB_SOUND_ENABLED = R.string.key_omnipod_notification_uncertain_smb_sound_enabled;
public static final int NOTIFICATION_UNCERTAIN_BOLUS_SOUND_ENABLED = R.string.key_omnipod_notification_uncertain_bolus_sound_enabled;
public static final int AUTOMATICALLY_ACKNOWLEDGE_ALERTS_ENABLED = R.string.key_omnipod_automatically_acknowledge_alerts_enabled;
public static final int RILEYLINK_STATS_BUTTON_ENABLED = R.string.key_omnipod_rileylink_stats_button_enabled;
}
public static class Statistics {

View file

@ -35,6 +35,7 @@ public enum PodHistoryEntryType {
CONFIGURE_ALERTS(50, R.string.omnipod_cmd_configure_alerts, PumpHistoryEntryGroup.Alarm),
ACKNOWLEDGE_ALERTS(51, R.string.omnipod_cmd_acknowledge_alerts, PumpHistoryEntryGroup.Alarm),
PLAY_TEST_BEEP(52, R.string.omnipod_cmd_play_test_beep, PumpHistoryEntryGroup.Alarm),
SUSPEND_DELIVERY(60, R.string.omnipod_cmd_suspend_delivery, PumpHistoryEntryGroup.Basal),
RESUME_DELIVERY(61, R.string.omnipod_cmd_resume_delivery, PumpHistoryEntryGroup.Basal),

View file

@ -0,0 +1,48 @@
package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action;
import org.joda.time.Duration;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.BeepConfigCommand;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.BeepConfigType;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager;
import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager;
public class ConfigureBeepAction implements OmnipodAction<StatusResponse> {
private final PodStateManager podStateManager;
private final BeepConfigType beepType;
private final boolean basalCompletionBeep;
private final Duration basalIntervalBeep;
private final boolean tempBasalCompletionBeep;
private final Duration tempBasalIntervalBeep;
private final boolean bolusCompletionBeep;
private final Duration bolusIntervalBeep;
public ConfigureBeepAction(PodStateManager podState, BeepConfigType beepType, boolean basalCompletionBeep, Duration basalIntervalBeep, boolean tempBasalCompletionBeep, Duration tempBasalIntervalBeep, boolean bolusCompletionBeep, Duration bolusIntervalBeep) {
if (podState == null || beepType == null) {
throw new IllegalArgumentException("Required parameter(s) missing");
}
this.beepType = beepType;
this.basalCompletionBeep = basalCompletionBeep;
this.basalIntervalBeep = basalIntervalBeep;
this.tempBasalCompletionBeep = tempBasalCompletionBeep;
this.tempBasalIntervalBeep = tempBasalIntervalBeep;
this.bolusCompletionBeep = bolusCompletionBeep;
this.bolusIntervalBeep = bolusIntervalBeep;
this.podStateManager = podState;
}
public ConfigureBeepAction(PodStateManager podState, BeepConfigType beepType) {
this(podState, beepType, false, Duration.ZERO, false, Duration.ZERO, false, Duration.ZERO);
}
@Override
public StatusResponse execute(OmnipodRileyLinkCommunicationManager communicationService) {
return communicationService.sendCommand(
StatusResponse.class, podStateManager,
new BeepConfigCommand(beepType, basalCompletionBeep, basalIntervalBeep,
tempBasalCompletionBeep, tempBasalIntervalBeep,
bolusCompletionBeep, bolusIntervalBeep));
}
}

View file

@ -58,7 +58,7 @@ public class InsertCannulaAction implements OmnipodAction<Void> {
if (podStateManager.getActivationProgress().needsCannulaInsertion()) {
communicationService.executeAction(new BolusAction(podStateManager, OmnipodConstants.POD_CANNULA_INSERTION_BOLUS_UNITS,
Duration.standardSeconds(1), false, false));
Duration.standardSeconds(1), false, true));
podStateManager.setActivationProgress(ActivationProgress.INSERTING_CANNULA);
}

View file

@ -32,6 +32,6 @@ public class PrimeService {
public StatusResponse executePrimeBolusCommand(OmnipodRileyLinkCommunicationManager communicationService, PodStateManager podStateManager) {
return communicationService.executeAction(new BolusAction(podStateManager, OmnipodConstants.POD_PRIME_BOLUS_UNITS,
Duration.standardSeconds(1), false, false));
Duration.standardSeconds(1), false, true));
}
}

View file

@ -30,10 +30,6 @@ public class BeepConfigCommand extends MessageBlock {
encode();
}
public BeepConfigCommand(BeepConfigType beepType) {
this(beepType, false, Duration.ZERO, false, Duration.ZERO, false, Duration.ZERO);
}
private void encode() {
encodedData = new byte[]{beepType.getValue()};
encodedData = ByteUtil.concat(encodedData, (byte) ((basalCompletionBeep ? (1 << 6) : 0) + (basalIntervalBeep.getStandardMinutes() & 0x3f)));

View file

@ -18,6 +18,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.acti
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.BolusAction;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.CancelDeliveryAction;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.ConfigureAlertsAction;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.ConfigureBeepAction;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.DeactivatePodAction;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.GetPodInfoAction;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.GetStatusAction;
@ -33,6 +34,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.mess
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoResponse;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.ActivationProgress;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertConfiguration;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.BeepConfigType;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.BeepType;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryStatus;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryType;
@ -171,6 +173,15 @@ public class OmnipodManager {
public synchronized void setBasalSchedule(BasalSchedule schedule, boolean acknowledgementBeep) {
assertReadyForDelivery();
if (!podStateManager.isBasalCertain()) {
try {
getPodStatus();
} catch (OmnipodException ex) {
ex.setCertainFailure(true);
throw ex;
}
}
boolean wasSuspended = podStateManager.isSuspended();
if (!wasSuspended) {
try {
@ -185,12 +196,17 @@ public class OmnipodManager {
}
}
BasalSchedule oldBasalSchedule = podStateManager.getBasalSchedule();
try {
podStateManager.setBasalSchedule(schedule);
podStateManager.setBasalCertain(false);
executeAndVerify(() -> communicationService.executeAction(new SetBasalScheduleAction(podStateManager, schedule,
false, podStateManager.getScheduleOffset(), acknowledgementBeep)));
podStateManager.setBasalSchedule(schedule);
} catch (OmnipodException ex) {
if (ex.isCertainFailure()) {
podStateManager.setBasalSchedule(oldBasalSchedule);
podStateManager.setBasalCertain(true);
if (!wasSuspended) {
throw new CommandFailedAfterChangingDeliveryStatusException("Suspending delivery succeeded but setting the new basal schedule did not", ex);
}
@ -206,6 +222,19 @@ public class OmnipodManager {
public synchronized void setTemporaryBasal(double rate, Duration duration, boolean acknowledgementBeep, boolean completionBeep) {
assertReadyForDelivery();
if (!podStateManager.isTempBasalCertain() || !podStateManager.isBasalCertain()) {
try {
getPodStatus();
} catch (OmnipodException ex) {
ex.setCertainFailure(true);
throw ex;
}
}
if (podStateManager.isSuspended()) {
throw new IllegalDeliveryStatusException(DeliveryStatus.NORMAL, DeliveryStatus.SUSPENDED);
}
boolean cancelCurrentTbr = podStateManager.isTempBasalRunning();
if (cancelCurrentTbr) {
@ -217,17 +246,19 @@ public class OmnipodManager {
}
// Uncertain failure
podStateManager.setTempBasalCertain(false);
throw new PrecedingCommandFailedUncertainlyException(ex);
}
}
try {
podStateManager.setTempBasal(DateTime.now().plus(OmnipodConstants.AVERAGE_TEMP_BASAL_COMMAND_COMMUNICATION_DURATION), rate, duration);
podStateManager.setTempBasalCertain(false);
executeAndVerify(() -> communicationService.executeAction(new SetTempBasalAction(
podStateManager, rate, duration, acknowledgementBeep, completionBeep)));
podStateManager.setTempBasal(DateTime.now().minus(OmnipodConstants.AVERAGE_TEMP_BASAL_COMMAND_COMMUNICATION_DURATION), rate, duration, true);
} catch (OmnipodException ex) {
if (ex.isCertainFailure()) {
podStateManager.clearTempBasal();
podStateManager.setTempBasalCertain(true);
if (cancelCurrentTbr) {
throw new CommandFailedAfterChangingDeliveryStatusException("Failed to set new TBR while cancelling old TBR succeeded", ex);
}
@ -235,7 +266,6 @@ public class OmnipodManager {
}
// Uncertain failure
podStateManager.setTempBasal(DateTime.now().minus(OmnipodConstants.AVERAGE_TEMP_BASAL_COMMAND_COMMUNICATION_DURATION), rate, duration, false);
throw ex;
}
}
@ -247,11 +277,33 @@ public class OmnipodManager {
private synchronized StatusResponse cancelDelivery(EnumSet<DeliveryType> deliveryTypes, boolean acknowledgementBeep) {
assertReadyForDelivery();
return executeAndVerify(() -> {
StatusResponse statusResponse = communicationService.executeAction(new CancelDeliveryAction(podStateManager, deliveryTypes, acknowledgementBeep));
aapsLogger.info(LTag.PUMPCOMM, "Status response after cancel delivery[types={}]: {}", deliveryTypes.toString(), statusResponse.toString());
return statusResponse;
});
if (deliveryTypes.contains(DeliveryType.BASAL)) {
podStateManager.setBasalCertain(false);
}
if (deliveryTypes.contains(DeliveryType.TEMP_BASAL)) {
podStateManager.setTempBasalCertain(false);
}
try {
return executeAndVerify(() -> {
StatusResponse statusResponse;
statusResponse = communicationService.executeAction(new CancelDeliveryAction(podStateManager, deliveryTypes, acknowledgementBeep));
aapsLogger.info(LTag.PUMPCOMM, "Status response after cancel delivery[types={}]: {}", deliveryTypes.toString(), statusResponse.toString());
return statusResponse;
});
} catch (OmnipodException ex) {
if (ex.isCertainFailure()) {
if (deliveryTypes.contains(DeliveryType.BASAL)) {
podStateManager.setBasalCertain(true);
}
if (deliveryTypes.contains(DeliveryType.TEMP_BASAL)) {
podStateManager.setTempBasalCertain(true);
}
}
throw ex;
}
}
// Returns a SingleSubject that returns when the bolus has finished.
@ -260,6 +312,19 @@ public class OmnipodManager {
public synchronized BolusCommandResult bolus(Double units, boolean acknowledgementBeep, boolean completionBeep, BiConsumer<Double, Integer> progressIndicationConsumer) {
assertReadyForDelivery();
if (!podStateManager.isBasalCertain()) {
try {
getPodStatus();
} catch (OmnipodException ex) {
ex.setCertainFailure(true);
throw ex;
}
}
if (podStateManager.isSuspended()) {
throw new IllegalDeliveryStatusException(DeliveryStatus.NORMAL, DeliveryStatus.SUSPENDED);
}
bolusCommandExecutionSubject = SingleSubject.create();
CommandDeliveryStatus commandDeliveryStatus = CommandDeliveryStatus.SUCCESS;
@ -427,6 +492,25 @@ public class OmnipodManager {
podStateManager.discardState();
}
public synchronized void configureBeeps(BeepConfigType beepType, boolean basalCompletionBeep, Duration basalIntervalBeep,
boolean tempBasalCompletionBeep, Duration tempBasalIntervalBeep,
boolean bolusCompletionBeep, Duration bolusIntervalBeep) {
if (!podStateManager.isPodInitialized()) {
throw new IllegalPodProgressException(PodProgressStatus.REMINDER_INITIALIZED, null);
}
communicationService.executeAction(new ConfigureBeepAction(
podStateManager, beepType, basalCompletionBeep,
basalIntervalBeep, tempBasalCompletionBeep, tempBasalIntervalBeep,
bolusCompletionBeep, bolusIntervalBeep));
}
public synchronized void playTestBeep(BeepConfigType beepType) {
if (!podStateManager.isPodInitialized()) {
throw new IllegalPodProgressException(PodProgressStatus.REMINDER_INITIALIZED, null);
}
communicationService.executeAction(new ConfigureBeepAction(podStateManager, beepType));
}
public OmnipodRileyLinkCommunicationManager getCommunicationService() {
return communicationService;
}

View file

@ -368,6 +368,15 @@ public abstract class PodStateManager {
setAndStore(() -> podState.setBasalSchedule(basalSchedule));
}
public final boolean isBasalCertain() {
Boolean certain = getSafe(() -> podState.isBasalCertain());
return certain == null || certain;
}
public final void setBasalCertain(boolean certain) {
setAndStore(() -> podState.setBasalCertain(certain));
}
public final DateTime getLastBolusStartTime() {
return getSafe(() -> podState.getLastBolusStartTime());
}
@ -416,14 +425,19 @@ public abstract class PodStateManager {
}
public final void setTempBasalCertain(boolean certain) {
setSafe(() -> podState.setTempBasalCertain(certain));
setAndStore(() -> {
if (!Objects.equals(podState.isTempBasalCertain(), certain)) {
podState.setTempBasalCertain(certain);
onTbrChanged();
}
});
}
public final void setTempBasal(DateTime startTime, Double amount, Duration duration, boolean certain) {
setTempBasal(startTime, amount, duration, certain, true);
public final void setTempBasal(DateTime startTime, Double amount, Duration duration) {
setTempBasal(startTime, amount, duration, true);
}
public final void setTempBasal(DateTime startTime, Double amount, Duration duration, Boolean certain, boolean store) {
private void setTempBasal(DateTime startTime, Double amount, Duration duration, boolean store) {
DateTime currentStartTime = getTempBasalStartTime();
Double currentAmount = getTempBasalAmount();
Duration currentDuration = getTempBasalDuration();
@ -432,7 +446,6 @@ public abstract class PodStateManager {
podState.setTempBasalStartTime(startTime);
podState.setTempBasalAmount(amount);
podState.setTempBasalDuration(duration);
podState.setTempBasalCertain(certain);
};
if (store) {
@ -444,6 +457,14 @@ public abstract class PodStateManager {
}
}
public final void clearTempBasal() {
clearTempBasal(true);
}
private void clearTempBasal(boolean store) {
setTempBasal(null, null, null, store);
}
/**
* @return true when a Temp Basal is stored in the Pod Stated
* Please note that this could also be an expired Temp Basal. For an indication on whether or not
@ -457,13 +478,22 @@ public abstract class PodStateManager {
* @return true when a Temp Basal is stored in the Pod State and this temp basal is currently running (based on start time and duration)
*/
public final boolean isTempBasalRunning() {
return isTempBasalRunningAt(DateTime.now());
return isTempBasalRunningAt(null);
}
/**
* @return true when a Temp Basal is stored in the Pod State and this temp basal is running at the given time (based on start time and duration)
* @param time the time for which to look up whether a temp basal is running, null meaning now
* @return true when a Temp Basal is stored in the Pod State and this temp basal is running at the given time (based on start time and duration),
* or when the time provided is null and the delivery status of the Pod inidicated that a TBR is running, but not TBR is stored
* This can happen in some rare cases.
*/
public final boolean isTempBasalRunningAt(DateTime time) {
if (time == null) { // now
if (!hasTempBasal() && getLastDeliveryStatus().isTbrRunning()) {
return true;
}
time = DateTime.now();
}
if (hasTempBasal()) {
DateTime tempBasalStartTime = getTempBasalStartTime();
DateTime tempBasalEndTime = tempBasalStartTime.plus(getTempBasalDuration());
@ -537,15 +567,26 @@ public abstract class PodStateManager {
podState.setTotalTicksDelivered(status.getTicksDelivered());
podState.setPodProgressStatus(status.getPodProgressStatus());
podState.setTimeActive(status.getTimeActive());
if (status.getDeliveryStatus().isTbrRunning()) {
if (!isTempBasalCertain() && isTempBasalRunning()) {
podState.setTempBasalCertain(true);
boolean isBasalCertain = podState.isBasalCertain() == null || podState.isBasalCertain();
boolean isTempBasalCertain = podState.isTempBasalCertain() == null || podState.isTempBasalCertain();
if (!status.getDeliveryStatus().isTbrRunning()) {
if (isTempBasalCertain) {
clearTempBasal(); // Triggers onTbrChanged when appropriate
} else {
// Don't trigger onTbrChanged as we will trigger onUncertainTbrRecovered below
podState.setTempBasalStartTime(null);
podState.setTempBasalAmount(null);
podState.setTempBasalDuration(null);
}
} else {
// Triggers {@link #onTbrChanged() onTbrChanged()} when appropriate
setTempBasal(null, null, null, true, false);
}
podState.setLastUpdatedFromResponse(DateTime.now());
if (!isTempBasalCertain) {
podState.setTempBasalCertain(true);
onUncertainTbrRecovered();
}
if (!isBasalCertain) {
podState.setBasalCertain(true);
}
if (status instanceof PodInfoDetailedStatus) {
PodInfoDetailedStatus detailedStatus = (PodInfoDetailedStatus) status;
@ -556,6 +597,8 @@ public abstract class PodStateManager {
}
}
}
podState.setLastUpdatedFromResponse(DateTime.now());
});
}
@ -564,6 +607,11 @@ public abstract class PodStateManager {
// Can be overridden in subclasses
}
protected void onUncertainTbrRecovered() {
// Deliberately left empty
// Can be overridden in subclasses
}
protected void onActiveAlertsChanged() {
// Deliberately left empty
// Can be overridden in subclasses
@ -667,6 +715,7 @@ public abstract class PodStateManager {
private DeliveryStatus lastDeliveryStatus;
private AlertSet activeAlerts;
private BasalSchedule basalSchedule;
private Boolean basalCertain;
private DateTime lastBolusStartTime;
private Double lastBolusAmount;
private Duration lastBolusDuration;
@ -871,6 +920,14 @@ public abstract class PodStateManager {
this.basalSchedule = basalSchedule;
}
Boolean isBasalCertain() {
return basalCertain;
}
void setBasalCertain(Boolean certain) {
this.basalCertain = certain;
}
DateTime getLastBolusStartTime() {
return lastBolusStartTime;
}

View file

@ -0,0 +1,8 @@
package info.nightscout.androidaps.plugins.pump.omnipod.event
import info.nightscout.androidaps.events.Event
/**
* Created by andy on 04.06.2018.
*/
class EventOmnipodUncertainTbrRecovered : Event()

View file

@ -1,5 +1,8 @@
package info.nightscout.androidaps.plugins.pump.omnipod.manager;
import android.content.Context;
import android.content.Intent;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.json.JSONException;
@ -14,6 +17,7 @@ import javax.inject.Inject;
import javax.inject.Singleton;
import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.activities.ErrorHelperActivity;
import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.PumpEnactResult;
@ -46,6 +50,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.mess
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoRecentPulseLog;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoResponse;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertConfiguration;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.BeepConfigType;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.FaultEventCode;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType;
@ -102,6 +107,7 @@ public class AapsOmnipodManager {
private final OmnipodAlertUtil omnipodAlertUtil;
private final NSUpload nsUpload;
private final ProfileFunction profileFunction;
private final Context context;
private boolean basalBeepsEnabled;
private boolean bolusBeepsEnabled;
@ -114,6 +120,8 @@ public class AapsOmnipodManager {
private boolean notificationUncertainSmbSoundEnabled;
private boolean notificationUncertainBolusSoundEnabled;
private boolean automaticallyAcknowledgeAlertsEnabled;
private boolean testBeepButtonEnabled;
private boolean rileylinkStatsButtonEnabled;
@Inject
public AapsOmnipodManager(OmnipodRileyLinkCommunicationManager communicationService,
@ -128,8 +136,9 @@ public class AapsOmnipodManager {
DatabaseHelperInterface databaseHelper,
OmnipodAlertUtil omnipodAlertUtil,
NSUpload nsUpload,
ProfileFunction profileFunction
) {
ProfileFunction profileFunction,
Context context) {
this.podStateManager = podStateManager;
this.aapsOmnipodUtil = aapsOmnipodUtil;
this.aapsLogger = aapsLogger;
@ -142,6 +151,7 @@ public class AapsOmnipodManager {
this.omnipodAlertUtil = omnipodAlertUtil;
this.nsUpload = nsUpload;
this.profileFunction = profileFunction;
this.context = context;
delegate = new OmnipodManager(aapsLogger, communicationService, podStateManager);
@ -152,9 +162,10 @@ public class AapsOmnipodManager {
basalBeepsEnabled = sp.getBoolean(OmnipodStorageKeys.Preferences.BASAL_BEEPS_ENABLED, true);
bolusBeepsEnabled = sp.getBoolean(OmnipodStorageKeys.Preferences.BOLUS_BEEPS_ENABLED, true);
smbBeepsEnabled = sp.getBoolean(OmnipodStorageKeys.Preferences.SMB_BEEPS_ENABLED, true);
tbrBeepsEnabled = sp.getBoolean(OmnipodStorageKeys.Preferences.TBR_BEEPS_ENABLED, true);
tbrBeepsEnabled = sp.getBoolean(OmnipodStorageKeys.Preferences.TBR_BEEPS_ENABLED, false);
suspendDeliveryButtonEnabled = sp.getBoolean(OmnipodStorageKeys.Preferences.SUSPEND_DELIVERY_BUTTON_ENABLED, false);
pulseLogButtonEnabled = sp.getBoolean(OmnipodStorageKeys.Preferences.PULSE_LOG_BUTTON_ENABLED, false);
rileylinkStatsButtonEnabled = sp.getBoolean(OmnipodStorageKeys.Preferences.RILEYLINK_STATS_BUTTON_ENABLED, false);
timeChangeEventEnabled = sp.getBoolean(OmnipodStorageKeys.Preferences.TIME_CHANGE_EVENT_ENABLED, true);
notificationUncertainTbrSoundEnabled = sp.getBoolean(OmnipodStorageKeys.Preferences.NOTIFICATION_UNCERTAIN_TBR_SOUND_ENABLED, true);
notificationUncertainSmbSoundEnabled = sp.getBoolean(OmnipodStorageKeys.Preferences.NOTIFICATION_UNCERTAIN_SMB_SOUND_ENABLED, true);
@ -232,6 +243,20 @@ public class AapsOmnipodManager {
return new PumpEnactResult(injector).success(true).enacted(false);
}
public PumpEnactResult playTestBeep(BeepConfigType beepType) {
try {
executeCommand(() -> delegate.playTestBeep(beepType));
} catch (Exception ex) {
String errorMessage = translateException(ex);
addFailureToHistory(PodHistoryEntryType.PLAY_TEST_BEEP, errorMessage);
return new PumpEnactResult(injector).success(false).enacted(false).comment(errorMessage);
}
addSuccessToHistory(PodHistoryEntryType.PLAY_TEST_BEEP, beepType);
return new PumpEnactResult(injector).success(true).enacted(false);
}
public PumpEnactResult getPodStatus() {
StatusResponse statusResponse;
@ -357,7 +382,7 @@ public class AapsOmnipodManager {
if (detailedBolusInfo.isSMB) {
showNotification(getStringResource(R.string.omnipod_error_bolus_failed_uncertain_smb, detailedBolusInfo.insulin), Notification.URGENT, isNotificationUncertainSmbSoundEnabled() ? R.raw.boluserror : null);
} else {
showNotification(getStringResource(R.string.omnipod_error_bolus_failed_uncertain), Notification.URGENT, isNotificationUncertainBolusSoundEnabled() ? R.raw.boluserror : null);
showErrorDialog(getStringResource(R.string.omnipod_error_bolus_failed_uncertain), isNotificationUncertainBolusSoundEnabled() ? R.raw.boluserror : null);
}
}
@ -613,6 +638,14 @@ public class AapsOmnipodManager {
return pulseLogButtonEnabled;
}
public boolean isTestBeepButtonEnabled() {
return testBeepButtonEnabled;
}
public boolean isRileylinkStatsButtonEnabled() {
return rileylinkStatsButtonEnabled;
}
public boolean isTimeChangeEventEnabled() {
return timeChangeEventEnabled;
}
@ -710,6 +743,10 @@ public class AapsOmnipodManager {
activePlugin.getActiveTreatments().addToHistoryTempBasal(temporaryBasal);
}
public long addTbrSuccessToHistory(long requestTime, TempBasalPair tempBasalPair) {
return addSuccessToHistory(requestTime, PodHistoryEntryType.SET_TEMPORARY_BASAL, tempBasalPair);
}
private void addTempBasalTreatment(long time, long pumpId, TempBasalPair tempBasalPair) {
TemporaryBasal tempStart = new TemporaryBasal(injector) //
.date(time) //
@ -850,6 +887,15 @@ public class AapsOmnipodManager {
rxBus.send(event);
}
private void showErrorDialog(String message, Integer sound) {
Intent intent = new Intent(context, ErrorHelperActivity.class);
intent.putExtra("soundid", sound);
intent.putExtra("status", message);
intent.putExtra("title", resourceHelper.gs(R.string.error));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
private void showPodFaultNotification(FaultEventCode faultEventCode) {
showPodFaultNotification(faultEventCode, R.raw.boluserror);
}

View file

@ -10,6 +10,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateMa
import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodActiveAlertsChanged;
import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodFaultEventChanged;
import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodTbrChanged;
import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodUncertainTbrRecovered;
import info.nightscout.androidaps.utils.sharedPreferences.SP;
@Singleton
@ -34,6 +35,10 @@ public class AapsPodStateManager extends PodStateManager {
sp.putString(OmnipodStorageKeys.Preferences.POD_STATE, podState);
}
@Override protected void onUncertainTbrRecovered() {
rxBus.send(new EventOmnipodUncertainTbrRecovered());
}
@Override protected void onTbrChanged() {
rxBus.send(new EventOmnipodTbrChanged());
}

View file

@ -0,0 +1,16 @@
package info.nightscout.androidaps.plugins.pump.omnipod.queue.command;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.BeepConfigType;
public class CommandPlayTestBeep extends OmnipodCustomCommand {
private BeepConfigType beepType;
public CommandPlayTestBeep(BeepConfigType beepType) {
super(OmnipodCustomCommandType.PLAY_TEST_BEEP);
this.beepType = beepType;
}
public BeepConfigType getBeepType() {
return beepType;
}
}

View file

@ -8,7 +8,9 @@ public enum OmnipodCustomCommandType {
RESUME_DELIVERY("RESUME DELIVERY"),
DEACTIVATE_POD("DEACTIVATE POD"),
HANDLE_TIME_CHANGE("HANDLE TIME CHANGE"),
UPDATE_ALERT_CONFIGURATION("UPDATE ALERT CONFIGURATION");
UPDATE_ALERT_CONFIGURATION("UPDATE ALERT CONFIGURATION"),
PLAY_TEST_BEEP("PLAY TEST BEEP")
;
private final String description;

View file

@ -19,7 +19,6 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyLinkStatusActivity
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData
import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodPumpPlugin
import info.nightscout.androidaps.plugins.pump.omnipod.R
@ -30,7 +29,11 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateMa
import info.nightscout.androidaps.plugins.pump.omnipod.driver.util.TimeUtil
import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged
import info.nightscout.androidaps.plugins.pump.omnipod.manager.AapsOmnipodManager
import info.nightscout.androidaps.plugins.pump.omnipod.queue.command.*
import info.nightscout.androidaps.plugins.pump.omnipod.queue.command.CommandAcknowledgeAlerts
import info.nightscout.androidaps.plugins.pump.omnipod.queue.command.CommandGetPodStatus
import info.nightscout.androidaps.plugins.pump.omnipod.queue.command.CommandHandleTimeChange
import info.nightscout.androidaps.plugins.pump.omnipod.queue.command.CommandResumeDelivery
import info.nightscout.androidaps.plugins.pump.omnipod.queue.command.CommandSuspendDelivery
import info.nightscout.androidaps.plugins.pump.omnipod.util.AapsOmnipodUtil
import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodAlertUtil
import info.nightscout.androidaps.queue.Callback
@ -119,14 +122,6 @@ class OmnipodOverviewFragment : DaggerFragment() {
DisplayResultDialogCallback(resourceHelper.gs(R.string.omnipod_error_failed_to_refresh_status), false))
}
omnipod_overview_button_rileylink_stats.setOnClickListener {
if (omnipodPumpPlugin.rileyLinkService?.verifyConfiguration() == true) {
startActivity(Intent(context, RileyLinkStatusActivity::class.java))
} else {
displayNotConfiguredDialog()
}
}
omnipod_overview_button_acknowledge_active_alerts.setOnClickListener {
disablePodActionButtons()
commandQueue.customCommand(CommandAcknowledgeAlerts(),
@ -147,12 +142,6 @@ class OmnipodOverviewFragment : DaggerFragment() {
DisplayResultDialogCallback(resourceHelper.gs(R.string.omnipod_error_failed_to_set_time), true)
.messageOnSuccess(resourceHelper.gs(R.string.omnipod_confirmation_time_on_pod_updated)))
}
omnipod_overview_button_pulse_log.setOnClickListener {
disablePodActionButtons()
commandQueue.customCommand(CommandReadPulseLog(),
DisplayResultDialogCallback(resourceHelper.gs(R.string.omnipod_error_failed_to_read_pulse_log), false))
}
}
override fun onResume() {
@ -361,11 +350,17 @@ class OmnipodOverviewFragment : DaggerFragment() {
}
} else {
if (podStateManager.podProgressStatus.isRunning) {
if (podStateManager.isSuspended) {
var status = if (podStateManager.isSuspended) {
resourceHelper.gs(R.string.omnipod_pod_status_suspended)
} else {
resourceHelper.gs(R.string.omnipod_pod_status_running)
}
if (!podStateManager.isBasalCertain) {
status += " (" + resourceHelper.gs(R.string.omnipod_uncertain) + ")"
}
status
} else if (podStateManager.podProgressStatus == PodProgressStatus.FAULT_EVENT_OCCURRED) {
resourceHelper.gs(R.string.omnipod_pod_status_pod_fault)
} else if (podStateManager.podProgressStatus == PodProgressStatus.INACTIVE) {
@ -375,7 +370,7 @@ class OmnipodOverviewFragment : DaggerFragment() {
}
}
val podStatusColor = if (!podStateManager.isPodActivationCompleted || podStateManager.isPodDead || podStateManager.isSuspended) {
val podStatusColor = if (!podStateManager.isPodActivationCompleted || podStateManager.isPodDead || podStateManager.isSuspended || (podStateManager.isPodRunning && !podStateManager.isBasalCertain)) {
Color.RED
} else {
Color.WHITE
@ -406,18 +401,36 @@ class OmnipodOverviewFragment : DaggerFragment() {
private fun updateTempBasal() {
if (podStateManager.isPodActivationCompleted && podStateManager.isTempBasalRunning) {
val now = DateTime.now()
if (!podStateManager.hasTempBasal()) {
omnipod_overview_temp_basal.text = "???"
omnipod_overview_temp_basal.setTextColor(Color.RED)
} else {
val now = DateTime.now()
val startTime = podStateManager.tempBasalStartTime
val amount = podStateManager.tempBasalAmount
val duration = podStateManager.tempBasalDuration
val startTime = podStateManager.tempBasalStartTime
val amount = podStateManager.tempBasalAmount
val duration = podStateManager.tempBasalDuration
val minutesRunning = Duration(startTime, now).standardMinutes
val minutesRunning = Duration(startTime, now).standardMinutes
var text: String
var text: String
val textColor: Int
text = resourceHelper.gs(R.string.omnipod_overview_temp_basal_value, amount, dateUtil.timeString(startTime.millis), minutesRunning, duration.standardMinutes)
if (podStateManager.isTempBasalCertain) {
textColor = Color.WHITE
} else {
textColor = Color.RED
text += " (" + resourceHelper.gs(R.string.omnipod_uncertain) + ")"
}
omnipod_overview_temp_basal.text = text
omnipod_overview_temp_basal.setTextColor(textColor)
}
} else {
var text = PLACEHOLDER
val textColor: Int
text = resourceHelper.gs(R.string.omnipod_overview_temp_basal_value, amount, dateUtil.timeString(startTime.millis), minutesRunning, duration.standardMinutes)
if (podStateManager.isTempBasalCertain) {
if (!podStateManager.isPodActivationCompleted || podStateManager.isTempBasalCertain) {
textColor = Color.WHITE
} else {
textColor = Color.RED
@ -426,9 +439,6 @@ class OmnipodOverviewFragment : DaggerFragment() {
omnipod_overview_temp_basal.text = text
omnipod_overview_temp_basal.setTextColor(textColor)
} else {
omnipod_overview_temp_basal.text = PLACEHOLDER
omnipod_overview_temp_basal.setTextColor(Color.WHITE)
}
}
@ -447,7 +457,6 @@ class OmnipodOverviewFragment : DaggerFragment() {
updateAcknowledgeAlertsButton()
updateSuspendDeliveryButton()
updateSetTimeButton()
updatePulseLogButton()
}
private fun disablePodActionButtons() {
@ -456,7 +465,6 @@ class OmnipodOverviewFragment : DaggerFragment() {
omnipod_overview_button_suspend_delivery.isEnabled = false
omnipod_overview_button_set_time.isEnabled = false
omnipod_overview_button_refresh_status.isEnabled = false
omnipod_overview_button_pulse_log.isEnabled = false
}
private fun updateRefreshStatusButton() {
@ -501,15 +509,6 @@ class OmnipodOverviewFragment : DaggerFragment() {
}
}
private fun updatePulseLogButton() {
if (omnipodManager.isPulseLogButtonEnabled) {
omnipod_overview_button_pulse_log.visibility = View.VISIBLE
omnipod_overview_button_pulse_log.isEnabled = podStateManager.isPodActivationCompleted && rileyLinkServiceData.rileyLinkServiceState.isReady && isQueueEmpty()
} else {
omnipod_overview_button_pulse_log.visibility = View.GONE
}
}
private fun displayNotConfiguredDialog() {
context?.let {
UIRunnable(Runnable {

View file

@ -35,6 +35,7 @@ import info.nightscout.androidaps.plugins.pump.common.defs.PumpType;
import info.nightscout.androidaps.plugins.pump.common.utils.ProfileUtil;
import info.nightscout.androidaps.plugins.pump.omnipod.R;
import info.nightscout.androidaps.plugins.pump.omnipod.definition.PodHistoryEntryType;
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.BeepConfigType;
import info.nightscout.androidaps.plugins.pump.omnipod.util.AapsOmnipodUtil;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
@ -272,6 +273,12 @@ public class PodHistoryActivity extends NoSplashAppCompatActivity {
}
break;
case PLAY_TEST_BEEP: {
if (historyEntry.getData() != null) {
valueView.setText(historyEntry.getData());
}
}
break;
case GET_POD_STATUS:
case GET_POD_INFO:
case SET_TIME:

View file

@ -1,25 +1,35 @@
package info.nightscout.androidaps.plugins.pump.omnipod.ui
import android.content.Context
import android.content.Intent
import android.os.Bundle
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.activities.ErrorHelperActivity
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
import info.nightscout.androidaps.interfaces.CommandQueueProvider
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyLinkStatusActivity
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData
import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodPumpPlugin
import info.nightscout.androidaps.plugins.pump.omnipod.R
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.ActivationProgress
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.BeepConfigType
import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager
import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged
import info.nightscout.androidaps.plugins.pump.omnipod.manager.AapsOmnipodManager
import info.nightscout.androidaps.plugins.pump.omnipod.queue.command.CommandPlayTestBeep
import info.nightscout.androidaps.plugins.pump.omnipod.queue.command.CommandReadPulseLog
import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.activation.PodActivationWizardActivity
import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.deactivation.PodDeactivationWizardActivity
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.queue.events.EventQueueChanged
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.extensions.plusAssign
import info.nightscout.androidaps.utils.extensions.toVisibility
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.ui.UIRunnable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.omnipod_pod_management.*
@ -38,6 +48,8 @@ class PodManagementActivity : NoSplashAppCompatActivity() {
@Inject lateinit var injector: HasAndroidInjector
@Inject lateinit var rileyLinkServiceData: RileyLinkServiceData
@Inject lateinit var aapsOmnipodManager: AapsOmnipodManager
@Inject lateinit var context: Context
@Inject lateinit var omnipodPumpPlugin: OmnipodPumpPlugin
private var disposables: CompositeDisposable = CompositeDisposable()
@ -55,11 +67,45 @@ class PodManagementActivity : NoSplashAppCompatActivity() {
omnipod_pod_management_button_discard_pod.setOnClickListener {
OKDialog.showConfirmation(this,
resourceHelper.gs(R.string.omnipod_pod_management_discard_pod_state_confirmation), Thread {
resourceHelper.gs(R.string.omnipod_pod_management_discard_pod_confirmation), Thread {
aapsOmnipodManager.discardPodState()
})
}
omnipod_pod_management_button_rileylink_stats.setOnClickListener {
if (omnipodPumpPlugin.rileyLinkService?.verifyConfiguration() == true) {
startActivity(Intent(context, RileyLinkStatusActivity::class.java))
} else {
displayNotConfiguredDialog()
}
}
omnipod_pod_management_button_play_test_beep.setOnClickListener {
omnipod_pod_management_button_play_test_beep.isEnabled = false
omnipod_pod_management_button_play_test_beep.setText(R.string.omnipod_pod_management_button_playing_test_beep)
commandQueue.customCommand(CommandPlayTestBeep(BeepConfigType.BEEEP), object : Callback() {
override fun run() {
if (!result.success) {
displayErrorDialog(resourceHelper.gs(R.string.omnipod_warning), resourceHelper.gs(R.string.omnipod_two_strings_concatenated_by_colon, resourceHelper.gs(R.string.omnipod_error_failed_to_play_test_beep), result.comment), false)
}
}
})
}
omnipod_pod_management_button_pulse_log.setOnClickListener {
omnipod_pod_management_button_pulse_log.isEnabled = false
omnipod_pod_management_button_pulse_log.setText(R.string.omnipod_pod_management_button_reading_pulse_log)
commandQueue.customCommand(CommandReadPulseLog(), object : Callback() {
override fun run() {
if (!result.success) {
displayErrorDialog(resourceHelper.gs(R.string.omnipod_warning), resourceHelper.gs(R.string.omnipod_two_strings_concatenated_by_colon, resourceHelper.gs(R.string.omnipod_error_failed_to_read_pulse_log), result.comment), false)
}
}
})
}
omnipod_pod_management_button_pod_history.setOnClickListener {
startActivity(Intent(this, PodHistoryActivity::class.java))
}
@ -75,6 +121,10 @@ class PodManagementActivity : NoSplashAppCompatActivity() {
.toObservable(EventOmnipodPumpValuesChanged::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ refreshButtons() }, { fabricPrivacy.logException(it) })
disposables += rxBus
.toObservable(EventQueueChanged::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ refreshButtons() }, { fabricPrivacy.logException(it) })
refreshButtons()
}
@ -88,24 +138,82 @@ class PodManagementActivity : NoSplashAppCompatActivity() {
// Only show the discard button to reset a cached Pod address before the Pod has actually been initialized
// Otherwise, users should use the Deactivate Pod Wizard. In case proper deactivation fails,
// they will get an option to discard the Pod state there
// TODO maybe rename this button and the confirmation dialog text (see onCreate)
val discardButtonEnabled = podStateManager.hasPodState() && !podStateManager.isPodInitialized
omnipod_pod_management_button_discard_pod.visibility = discardButtonEnabled.toVisibility()
val pulseLogButtonEnabled = aapsOmnipodManager.isPulseLogButtonEnabled
omnipod_pod_management_button_pulse_log.visibility = pulseLogButtonEnabled.toVisibility()
omnipod_pod_management_button_rileylink_stats.visibility = aapsOmnipodManager.isRileylinkStatsButtonEnabled.toVisibility()
omnipod_pod_management_waiting_for_rl_layout.visibility = (!rileyLinkServiceData.rileyLinkServiceState.isReady).toVisibility()
if (rileyLinkServiceData.rileyLinkServiceState.isReady) {
omnipod_pod_management_button_activate_pod.isEnabled = !podStateManager.isPodActivationCompleted
omnipod_pod_management_button_deactivate_pod.isEnabled = podStateManager.activationProgress.isAtLeast(ActivationProgress.PAIRING_COMPLETED)
if (podStateManager.isPodInitialized && podStateManager.activationProgress.isAtLeast(ActivationProgress.PAIRING_COMPLETED)) {
if (commandQueue.isCustomCommandInQueue(CommandPlayTestBeep::class.java)) {
omnipod_pod_management_button_play_test_beep.isEnabled = false
omnipod_pod_management_button_play_test_beep.setText(R.string.omnipod_pod_management_button_playing_test_beep)
} else {
omnipod_pod_management_button_play_test_beep.isEnabled = true
omnipod_pod_management_button_play_test_beep.setText(R.string.omnipod_pod_management_button_play_test_beep)
}
} else {
omnipod_pod_management_button_play_test_beep.isEnabled = false
omnipod_pod_management_button_play_test_beep.setText(R.string.omnipod_pod_management_button_play_test_beep)
}
if (discardButtonEnabled) {
omnipod_pod_management_button_discard_pod.isEnabled = true
}
if (pulseLogButtonEnabled) {
if (podStateManager.isPodActivationCompleted) {
if (commandQueue.isCustomCommandInQueue(CommandReadPulseLog::class.java)) {
omnipod_pod_management_button_pulse_log.isEnabled = false
omnipod_pod_management_button_pulse_log.setText(R.string.omnipod_pod_management_button_reading_pulse_log)
} else {
omnipod_pod_management_button_pulse_log.isEnabled = true
omnipod_pod_management_button_pulse_log.setText(R.string.omnipod_pod_management_button_read_pulse_log)
}
} else {
omnipod_pod_management_button_pulse_log.isEnabled = false
omnipod_pod_management_button_pulse_log.setText(R.string.omnipod_pod_management_button_read_pulse_log)
}
}
} else {
omnipod_pod_management_button_play_test_beep.setText(R.string.omnipod_pod_management_button_play_test_beep)
omnipod_pod_management_button_activate_pod.isEnabled = false
omnipod_pod_management_button_deactivate_pod.isEnabled = false
omnipod_pod_management_button_play_test_beep.isEnabled = false
if (discardButtonEnabled) {
omnipod_pod_management_button_discard_pod.isEnabled = false
}
if (pulseLogButtonEnabled) {
omnipod_pod_management_button_pulse_log.isEnabled = false
omnipod_pod_management_button_pulse_log.setText(R.string.omnipod_pod_management_button_read_pulse_log)
}
}
}
private fun displayErrorDialog(title: String, message: String, withSound: Boolean) {
context.let {
val i = Intent(it, ErrorHelperActivity::class.java)
i.putExtra("soundid", if (withSound) R.raw.boluserror else 0)
i.putExtra("status", message)
i.putExtra("title", title)
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
it.startActivity(i)
}
}
private fun displayNotConfiguredDialog() {
context?.let {
UIRunnable(Runnable {
OKDialog.show(it, resourceHelper.gs(R.string.omnipod_warning),
resourceHelper.gs(R.string.omnipod_error_operation_not_possible_no_configuration), null)
}).run()
}
}
}

View file

@ -0,0 +1,9 @@
<vector android:height="48dp" android:viewportHeight="75"
android:viewportWidth="75" android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#AF2E9A"
android:pathData="m39,14 l-17,15H6V48H22l17,15z"
android:strokeColor="#AF2E9A" android:strokeLineJoin="round" android:strokeWidth="5"/>
<path android:fillColor="#00000000"
android:pathData="m49,26 l20,24m0,-24 l-20,24"
android:strokeColor="#AF2E9A" android:strokeLineCap="round" android:strokeWidth="5"/>
</vector>

View file

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M18.71,11.606h-0.736c-0.198,-3.001 -2.579,-5.382 -5.58,-5.58V5.29c0,-0.218 -0.177,-0.394 -0.394,-0.394s-0.394,0.177 -0.394,0.394v0.736c-3.001,0.198 -5.382,2.579 -5.58,5.58H5.29c-0.218,0 -0.394,0.177 -0.394,0.394s0.177,0.394 0.394,0.394h0.736c0.198,3.001 2.579,5.382 5.58,5.58v0.736c0,0.217 0.177,0.394 0.394,0.394s0.394,-0.177 0.394,-0.394v-0.736c3.001,-0.198 5.382,-2.579 5.58,-5.58h0.736c0.217,0 0.394,-0.177 0.394,-0.394S18.927,11.606 18.71,11.606zM17.143,11.606h-1.944c-0.179,-1.478 -1.331,-2.643 -2.804,-2.841V6.85C14.939,7.044 16.953,9.06 17.143,11.606zM13.542,12.394h0.938c-0.171,1.079 -1.01,1.93 -2.085,2.115v-0.967c0,-0.217 -0.177,-0.394 -0.394,-0.394s-0.394,0.177 -0.394,0.394v0.975c-1.111,-0.156 -1.988,-1.017 -2.163,-2.122h1.016c0.218,0 0.394,-0.177 0.394,-0.394s-0.177,-0.394 -0.394,-0.394H9.442c0.171,-1.111 1.049,-1.978 2.164,-2.134v0.987c0,0.218 0.177,0.394 0.394,0.394s0.394,-0.177 0.394,-0.394v-0.98c1.079,0.185 1.92,1.041 2.086,2.126h-0.939c-0.217,0 -0.394,0.177 -0.394,0.394S13.324,12.394 13.542,12.394zM11.606,6.851v1.906C10.095,8.921 8.903,10.1 8.72,11.606H6.864C7.053,9.062 9.064,7.047 11.606,6.851zM6.866,12.394H8.72c0.183,1.505 1.374,2.684 2.885,2.849v1.884C9.071,16.931 7.065,14.928 6.866,12.394zM12.394,17.128v-1.893c1.473,-0.197 2.625,-1.362 2.804,-2.841h1.942C16.941,14.93 14.932,16.935 12.394,17.128z"
android:fillColor="#36FF00" />
</vector>

View file

@ -0,0 +1,5 @@
<vector android:height="48dp" android:viewportHeight="310"
android:viewportWidth="310" android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#169100" android:pathData="M221.742,46.906c-7.28,-3.954 -16.387,-1.259 -20.341,6.021c-3.955,7.279 -1.259,16.386 6.02,20.341C242.937,92.561 265,129.626 265,170c0,60.654 -49.346,110 -110,110S45,230.654 45,170c0,-40.198 21.921,-77.186 57.208,-96.531c7.265,-3.982 9.925,-13.1 5.943,-20.364c-3.983,-7.264 -13.101,-9.925 -20.364,-5.943C42.891,71.775 15,118.844 15,170c0,77.196 62.804,140 140,140s140,-62.804 140,-140C295,118.62 266.929,71.453 221.742,46.906z"/>
<path android:fillColor="#169100" android:pathData="M155,130c8.284,0 15,-6.716 15,-15V15c0,-8.284 -6.716,-15 -15,-15c-8.284,0 -15,6.716 -15,15v100C140,123.284 146.716,130 155,130z"/>
</vector>

View file

@ -1,21 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M12,17.813m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"
android:fillColor="#E93057" />
<path
android:pathData="M19.357,6.125c0.195,-0.196 0.195,-0.512 0,-0.708c-0.195,-0.195 -0.512,-0.195 -0.707,0l-2.364,2.364C14.916,7.314 13.477,7.062 12,7.062c-2.902,0 -5.674,0.925 -8.015,2.675c-0.222,0.166 -0.267,0.479 -0.102,0.7c0.166,0.222 0.479,0.266 0.7,0.102C6.751,8.919 9.315,8.063 12,8.063c1.198,0 2.369,0.177 3.493,0.512l-1.829,1.829c-0.547,-0.093 -1.1,-0.154 -1.663,-0.154c-2.212,0 -4.325,0.705 -6.111,2.039c-0.222,0.166 -0.267,0.479 -0.102,0.701c0.166,0.221 0.478,0.267 0.7,0.101C8.099,11.887 10.005,11.25 12,11.25c0.26,0 0.516,0.022 0.773,0.044l-2.215,2.215c-1.012,0.201 -1.989,0.596 -2.839,1.231c-0.222,0.165 -0.267,0.479 -0.102,0.7c0.166,0.22 0.479,0.268 0.7,0.101c0.192,-0.143 0.392,-0.271 0.597,-0.389l-2.618,2.618c-0.195,0.195 -0.195,0.512 0,0.707c0.098,0.098 0.226,0.146 0.354,0.146s0.256,-0.049 0.354,-0.146L19.357,6.125z"
android:fillColor="#E93057" />
<path
android:pathData="M20.016,9.737c-0.562,-0.42 -1.15,-0.789 -1.757,-1.113L17.513,9.37c0.66,0.331 1.299,0.717 1.903,1.169c0.09,0.067 0.195,0.1 0.3,0.1c0.152,0 0.303,-0.069 0.4,-0.201C20.282,10.216 20.236,9.902 20.016,9.737z"
android:fillColor="#E93057" />
<path
android:pathData="M15.867,11.016l-0.776,0.776c0.856,0.307 1.671,0.739 2.421,1.298c0.09,0.067 0.195,0.1 0.3,0.1c0.152,0 0.303,-0.069 0.4,-0.2c0.166,-0.222 0.12,-0.535 -0.101,-0.701C17.409,11.764 16.656,11.341 15.867,11.016z"
android:fillColor="#E93057" />
<path
android:pathData="M13.394,13.489l-0.887,0.887c1.13,0.091 2.24,0.467 3.176,1.166c0.09,0.067 0.195,0.1 0.3,0.1c0.152,0 0.303,-0.069 0.4,-0.2c0.166,-0.222 0.12,-0.535 -0.101,-0.7C15.418,14.095 14.424,13.688 13.394,13.489z"
android:fillColor="#E93057" />
</vector>

View file

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M23.706,7.373c-0.149,-0.541 -0.728,-0.854 -1.294,-0.699L19.87,7.373c-0.325,-0.913 -1.301,-1.438 -2.255,-1.175l-3.008,0.826c-0.954,0.262 -1.525,1.212 -1.338,2.163l-2.542,0.698c-0.499,0.137 -0.799,0.593 -0.767,1.07c-1.696,0.439 -3.037,0.067 -4.101,-0.248c-1.047,-0.309 -1.951,-0.578 -2.713,0.152c-1.307,1.253 -0.369,2.87 0.384,4.17c0.501,0.863 1.019,1.757 0.766,2.3c-0.519,1.124 -2.729,1.128 -3.537,1.033c-0.203,-0.022 -0.392,0.122 -0.417,0.328c-0.024,0.206 0.123,0.391 0.329,0.414c0.086,0.01 1.376,0.152 2.554,-0.172c0.734,-0.202 1.424,-0.585 1.753,-1.292c0.416,-0.896 -0.173,-1.912 -0.797,-2.987c-0.844,-1.456 -1.336,-2.47 -0.515,-3.257c0.426,-0.409 0.972,-0.272 1.977,0.026c1.128,0.334 2.648,0.808 4.674,0.215c0.255,0.206 0.598,0.304 0.949,0.207l5.63,-1.547l2.016,7.338l0.127,-1.203l-1.718,-6.252l5.63,-1.547C23.517,8.479 23.855,7.914 23.706,7.373z"
android:fillColor="#67DFE8" />
</vector>

View file

@ -0,0 +1,5 @@
<vector android:height="48dp" android:viewportHeight="310"
android:viewportWidth="310" android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#BA4242" android:pathData="M221.742,46.906c-7.28,-3.954 -16.387,-1.259 -20.341,6.021c-3.955,7.279 -1.259,16.386 6.02,20.341C242.937,92.561 265,129.626 265,170c0,60.654 -49.346,110 -110,110S45,230.654 45,170c0,-40.198 21.921,-77.186 57.208,-96.531c7.265,-3.982 9.925,-13.1 5.943,-20.364c-3.983,-7.264 -13.101,-9.925 -20.364,-5.943C42.891,71.775 15,118.844 15,170c0,77.196 62.804,140 140,140s140,-62.804 140,-140C295,118.62 266.929,71.453 221.742,46.906z"/>
<path android:fillColor="#BA4242" android:pathData="M155,130c8.284,0 15,-6.716 15,-15V15c0,-8.284 -6.716,-15 -15,-15c-8.284,0 -15,6.716 -15,15v100C140,123.284 146.716,130 155,130z"/>
</vector>

View file

@ -1,10 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:tint="@color/toastInfo"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#000"
android:fillColor="#007BB3"
android:pathData="M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19M8.46,11.88L9.87,10.47L12,12.59L14.12,10.47L15.53,11.88L13.41,14L15.53,16.12L14.12,17.53L12,15.41L9.88,17.53L8.47,16.12L10.59,14L8.46,11.88M15.5,4L14.5,3H9.5L8.5,4H5V6H19V4H15.5Z" />
</vector>

View file

@ -1,12 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M12.069,20.423c-4.644,0 -8.422,-3.779 -8.422,-8.423s3.778,-8.422 8.422,-8.422S20.492,7.355 20.492,12S16.713,20.423 12.069,20.423zM12.069,4.943c-3.891,0 -7.057,3.166 -7.057,7.057c0,3.891 3.166,7.057 7.057,7.057c3.891,0 7.057,-3.166 7.057,-7.057C19.126,8.109 15.961,4.943 12.069,4.943z"
android:fillColor="#67DFE8" />
<path
android:pathData="M9.945,16.362c-0.113,0 -0.227,-0.028 -0.33,-0.085c-0.217,-0.12 -0.353,-0.349 -0.353,-0.598V8.32c0,-0.249 0.135,-0.478 0.353,-0.598c0.218,-0.12 0.485,-0.112 0.694,0.021l5.827,3.679c0.198,0.125 0.318,0.343 0.318,0.577s-0.12,0.452 -0.318,0.577l-5.827,3.679C10.198,16.326 10.072,16.362 9.945,16.362zM10.627,9.559v4.881L14.493,12L10.627,9.559z"
android:fillColor="#67DFE8" />
</vector>

View file

@ -1,15 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M24,9.343l-5.781,-3.968l-1.328,6.688l2.102,-1.757c0.014,0.056 0.03,0.111 0.043,0.168c0.116,0.512 0.183,1.042 0.183,1.589c0,3.952 -3.204,7.156 -7.156,7.156s-7.156,-3.204 -7.156,-7.156s3.204,-7.156 7.156,-7.156c1.072,0 2.085,0.242 2.998,0.665c0.325,0.151 0.639,0.321 0.936,0.517l0.002,-0.002l-0.352,-1.784l1.876,-0.538c-1.567,-1.033 -3.442,-1.639 -5.46,-1.639c-5.488,0 -9.938,4.449 -9.938,9.938S6.574,22 12.063,22S22,17.551 22,12.063c0,-0.759 -0.093,-1.496 -0.254,-2.206c-0.04,-0.176 -0.085,-0.35 -0.134,-0.523L24,9.343L24,9.343z"
android:fillColor="#FF1313" />
<path
android:pathData="M10.2429,8.7408l5.0162,5.0162l-1.5026,1.5026l-5.0162,-5.0162z"
android:fillColor="#FF1313" />
<path
android:pathData="M8.7408,13.7571l5.0162,-5.0162l1.5026,1.5026l-5.0162,5.0162z"
android:fillColor="#FF1313" />
</vector>

View file

@ -0,0 +1,14 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:height="48dp"
android:viewportHeight="75"
android:viewportWidth="75"
android:width="48dp"
>
<path android:fillColor="#D36200"
android:pathData="M39.389,13.769L22.235,28.606L6,28.606L6,47.699L21.989,47.699L39.389,62.75L39.389,13.769z"
android:strokeColor="#D36200" android:strokeLineJoin="round" android:strokeWidth="5"/>
<path android:fillColor="#00000000"
android:pathData="M48,27.6a19.5,19.5 0,0 1,0 21.4M55.1,20.5a30,30 0,0 1,0 35.6M61.6,14a38.8,38.8 0,0 1,0 48.6"
android:strokeColor="#D36200" android:strokeLineCap="round" android:strokeWidth="5"/>
</vector>

View file

@ -0,0 +1,7 @@
<vector android:height="48dp" android:viewportHeight="484"
android:viewportWidth="484" android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#D36200" android:pathData="M410.413,70.88C364.706,25.172 303.934,0 239.293,0c-47.493,0 -93.076,13.591 -132.383,39.378l-2.909,-2.985C93.086,25.194 77.521,20.808 62.366,24.662c-15.155,3.854 -26.735,15.14 -30.975,30.192L4.369,150.781c-4.239,15.05 -0.255,30.72 10.658,41.917c8.308,8.524 19.31,13.101 30.775,13.101c3.595,0 7.236,-0.45 10.854,-1.37l96.591,-24.548c15.156,-3.852 26.736,-15.137 30.978,-30.189c3.54,-12.562 1.331,-25.547 -5.836,-36.012C197.287,104.713 218.107,100 239.293,100c78.299,0 142,63.701 142,142s-63.701,142 -142,142c-40.717,0 -79.54,-17.527 -106.514,-48.087c-18.243,-20.667 -49.903,-22.642 -70.573,-4.399c-10.013,8.838 -15.985,21.046 -16.816,34.376c-0.831,13.329 3.579,26.185 12.417,36.198C103.753,454.144 169.903,484 239.293,484c64.641,0 125.414,-25.172 171.121,-70.88c45.708,-45.708 70.88,-106.479 70.88,-171.12S456.121,116.588 410.413,70.88zM164.975,144.269c-2.28,8.092 -8.506,14.159 -16.654,16.23L51.73,185.046c-8.146,2.072 -16.513,-0.287 -22.38,-6.307c-5.867,-6.02 -8.009,-14.444 -5.73,-22.536l27.023,-95.928c2.279,-8.092 8.504,-14.16 16.652,-16.231c8.15,-2.071 16.516,0.286 22.383,6.307l33.072,33.933l32.604,33.454c0.003,0.003 0.006,0.005 0.009,0.008l3.883,3.984C165.113,127.751 167.255,136.177 164.975,144.269zM396.271,398.978C354.341,440.908 298.592,464 239.293,464c-63.656,0 -124.34,-27.39 -166.492,-75.147c-5.303,-6.008 -7.948,-13.722 -7.45,-21.719s4.082,-15.323 10.089,-20.625c5.695,-5.026 12.777,-7.494 19.835,-7.494c8.313,0 16.589,3.427 22.51,10.133C148.553,384.007 192.841,404 239.293,404c89.328,0 162,-72.673 162,-162s-72.673,-162 -162,-162c-26.21,0 -51.956,6.312 -74.942,18.314l-11.509,-11.809l-31.691,-32.517C156.439,31.715 197.037,20 239.293,20c59.299,0 115.048,23.092 156.978,65.022c41.931,41.93 65.022,97.679 65.022,156.978S438.201,357.047 396.271,398.978z"/>
<path android:fillColor="#FFFFBC4F" android:pathData="M420.202,336.007c-1.397,0 -2.817,-0.294 -4.17,-0.916c-5.019,-2.306 -7.217,-8.244 -4.911,-13.262c11.395,-24.793 17.172,-51.315 17.172,-78.829c0,-35.76 -10.031,-70.57 -29.01,-100.666c-2.945,-4.672 -1.547,-10.847 3.125,-13.792c4.672,-2.948 10.846,-1.547 13.793,3.125c20.994,33.294 32.092,71.793 32.092,111.334c0,30.417 -6.392,59.749 -18.999,87.18C427.611,333.846 423.987,336.007 420.202,336.007z"/>
<path android:fillColor="#FFFFBC4F" android:pathData="M375.291,107.724c-2.45,0 -4.904,-0.895 -6.834,-2.701c-13.866,-12.987 -29.525,-23.772 -46.542,-32.057c-4.966,-2.418 -7.031,-8.403 -4.614,-13.369c2.417,-4.965 8.403,-7.031 13.368,-4.614c18.817,9.162 36.131,21.086 51.46,35.442c4.031,3.775 4.238,10.104 0.463,14.135C380.623,106.662 377.96,107.724 375.291,107.724z"/>
<path android:fillColor="#D36200" android:pathData="M284.002,329c-8.014,0 -15.548,-3.121 -21.214,-8.787l-44.499,-44.5c-5.675,-5.675 -8.784,-13.202 -8.776,-21.228c-0.007,-0.161 -0.011,-0.322 -0.011,-0.485V151c0,-16.542 13.458,-30 30,-30s30,13.458 30,30v91.073l35.714,35.713v0c11.695,11.697 11.695,30.729 0,42.426C299.55,325.879 292.016,329 284.002,329zM229.502,253.729c0.006,0.132 0.01,0.263 0.012,0.396c0.001,0.083 0,0.165 0,0.248c-0.035,2.726 1.001,5.283 2.918,7.199l44.499,44.5c1.889,1.889 4.4,2.929 7.071,2.929s5.183,-1.04 7.071,-2.929c3.898,-3.898 3.898,-10.243 0,-14.142l-38.643,-38.642c-1.875,-1.875 -2.929,-4.419 -2.929,-7.071V151c0,-5.514 -4.486,-10 -10,-10c-5.514,0 -10,4.486 -10,10V253.729z"/>
</vector>

View file

@ -0,0 +1,5 @@
<vector android:height="48dp" android:viewportHeight="490"
android:viewportWidth="490" android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#4D71F1" android:pathData="M490,305V185h-69.964c-2.498,-7.291 -5.453,-14.42 -8.844,-21.34l49.475,-49.475l-84.853,-84.853L326.34,78.807c-6.919,-3.39 -14.051,-6.345 -21.34,-8.843V0H185v69.964c-7.29,2.498 -14.42,5.453 -21.34,8.843l-49.475,-49.475l-84.853,84.853l49.475,49.475c-3.391,6.92 -6.345,14.05 -8.843,21.34H0v120h69.964c2.498,7.291 5.453,14.42 8.843,21.34l-49.475,49.475l84.853,84.853l49.475,-49.475c6.92,3.391 14.05,6.345 21.34,8.843V490h120v-69.964c7.29,-2.498 14.42,-5.453 21.34,-8.843l49.475,49.475l84.853,-84.853l-49.475,-49.475c3.391,-6.919 6.346,-14.05 8.844,-21.34H490zM418.241,375.815l-42.427,42.426l-44.187,-44.186l-9.944,5.673c-11.206,6.394 -23.199,11.364 -35.646,14.772L275,397.523V460h-60v-62.477l-11.039,-3.022c-12.445,-3.408 -24.438,-8.378 -35.646,-14.772l-9.944,-5.673l-44.186,44.186l-42.426,-42.426l44.186,-44.186l-5.673,-9.944c-6.394,-11.206 -11.364,-23.199 -14.772,-35.646L92.478,275H30v-60h62.478l3.022,-11.039c3.408,-12.445 8.377,-24.438 14.771,-35.645l5.674,-9.944l-44.187,-44.187l42.426,-42.426l44.187,44.187l9.944,-5.674c11.207,-6.394 23.2,-11.364 35.645,-14.771L215,92.478V30h60v62.478l11.039,3.022c12.446,3.408 24.438,8.378 35.645,14.771l9.944,5.674l44.187,-44.187l42.427,42.426l-44.187,44.187l5.674,9.944c6.393,11.205 11.363,23.198 14.772,35.646L397.523,215H460v60h-62.477l-3.022,11.038c-3.409,12.447 -8.38,24.44 -14.772,35.646l-5.674,9.944L418.241,375.815z"/>
<path android:fillColor="#4D71F1" android:pathData="M245,150c-52.383,0 -95,42.617 -95,95s42.617,95 95,95s95,-42.617 95,-95S297.383,150 245,150zM245,310c-35.841,0 -65,-29.159 -65,-65s29.159,-65 65,-65s65,29.159 65,65S280.841,310 245,310z"/>
</vector>

View file

@ -5,8 +5,8 @@
android:viewportHeight="24">
<path
android:pathData="M16.578,18.026l0,-11.042l-3.698,0l0,11.042l-9.363,0l0,-1.01l8.354,0l0,-11.041l5.717,0l0,11.041l1.645,0l0,1.01z"
android:fillColor="#E93057" />
android:fillColor="#A14FFF" />
<path
android:pathData="M2.852,13.946c-0.248,0 -0.498,-0.123 -0.74,-0.366c-0.49,-0.49 -0.492,-0.986 -0.004,-1.474l3.125,-3.125C5.106,8.737 5.048,8.435 5.048,8.136c0,-1.336 1.172,-2.508 2.508,-2.508c0.282,0 0.572,0.055 0.864,0.163c0.186,0.069 0.347,0.148 0.493,0.242L8.547,6.484L7.431,7.6l0.731,0.661l1.046,-1.116l0.374,-0.374c0.171,0.154 0.25,0.315 0.319,0.501c0.108,0.292 0.163,0.583 0.163,0.864c0,0.67 -0.261,1.3 -0.734,1.773c-0.473,0.474 -1.103,0.734 -1.773,0.735c-0.298,0 -0.6,-0.058 -0.898,-0.173l-3.072,3.113C3.346,13.824 3.099,13.946 2.852,13.946zM7.556,6.237c-0.507,0 -0.984,0.198 -1.342,0.556C5.855,7.152 5.657,7.629 5.657,8.136c0,0.153 0.024,0.313 0.076,0.5c0.046,0.168 0.114,0.326 0.2,0.47l0.022,0.037c0,0 -0.139,0.115 -0.168,0.146l-3.249,3.248c-0.26,0.26 -0.227,0.381 0.004,0.612c0.134,0.134 0.219,0.186 0.304,0.186c0.085,0 0.184,-0.058 0.308,-0.182l3.249,-3.249c0.03,-0.03 0.104,-0.12 0.104,-0.12l0.078,-0.026c0.146,0.087 0.304,0.155 0.471,0.2c0.186,0.052 0.344,0.076 0.499,0.076c1.009,0 1.896,-0.887 1.898,-1.898c0,-0.134 -0.018,-0.274 -0.054,-0.43L8.342,8.872C8.284,8.929 8.208,8.961 8.126,8.961c-0.081,0 -0.158,-0.032 -0.215,-0.089L6.82,7.78c-0.119,-0.119 -0.119,-0.313 0,-0.431l1.143,-1.142C7.886,6.235 7.807,6.241 7.729,6.241C7.67,6.241 7.556,6.237 7.556,6.237z"
android:fillColor="#E93057" />
android:fillColor="#FFBC4F" />
</vector>

View file

@ -0,0 +1,5 @@
<vector android:height="48dp" android:viewportHeight="492.883"
android:viewportWidth="492.883" android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#00838F" android:pathData="M122.941,374.241c-20.1,-18.1 -34.6,-39.8 -44.1,-63.1c-25.2,-61.8 -13.4,-135.3 35.8,-186l45.4,45.4c2.5,2.5 7,0.7 7.6,-3l24.8,-162.3c0.4,-2.7 -1.9,-5 -4.6,-4.6l-162.4,24.8c-3.7,0.6 -5.5,5.1 -3,7.6l45.5,45.5c-75.1,76.8 -87.9,192 -38.6,282c14.8,27.1 35.3,51.9 61.4,72.7c44.4,35.3 99,52.2 153.2,51.1l10.2,-66.7C207.441,421.641 159.441,407.241 122.941,374.241z"/>
<path android:fillColor="#00838F" android:pathData="M424.941,414.341c75.1,-76.8 87.9,-192 38.6,-282c-14.8,-27.1 -35.3,-51.9 -61.4,-72.7c-44.4,-35.3 -99,-52.2 -153.2,-51.1l-10.2,66.7c46.6,-4 94.7,10.4 131.2,43.4c20.1,18.1 34.6,39.8 44.1,63.1c25.2,61.8 13.4,135.3 -35.8,186l-45.4,-45.4c-2.5,-2.5 -7,-0.7 -7.6,3l-24.8,162.3c-0.4,2.7 1.9,5 4.6,4.6l162.4,-24.8c3.7,-0.6 5.4,-5.1 3,-7.6L424.941,414.341z"/>
</vector>

View file

@ -0,0 +1,5 @@
<vector android:height="48dp" android:viewportHeight="330"
android:viewportWidth="330" android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#169100" android:pathData="M236.95,152.281l-108,-67.501c-4.624,-2.89 -10.453,-3.044 -15.222,-0.4C108.959,87.024 106,92.047 106,97.5v135c0,5.453 2.959,10.476 7.728,13.12c2.266,1.256 4.77,1.88 7.271,1.88c2.763,0 5.523,-0.763 7.95,-2.28l108,-67.499c4.386,-2.741 7.05,-7.548 7.05,-12.72C244,159.829 241.336,155.022 236.95,152.281z"/>
<path android:fillColor="#169100" android:pathData="M165,0C74.019,0 0,74.019 0,165s74.019,165 165,165s165,-74.019 165,-165S255.981,0 165,0zM165,300c-74.44,0 -135,-60.561 -135,-135S90.56,30 165,30s135,60.561 135,135S239.439,300 165,300z"/>
</vector>

View file

@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M5.719,19.125L5.719,11.828"
android:strokeWidth="2.2677"
android:fillColor="#00000000"
android:strokeColor="#FEAF05"
android:strokeLineCap="round"/>
<path
android:pathData="M9.792,19.125L9.792,8.01"
android:strokeWidth="2.2677"
android:fillColor="#00000000"
android:strokeColor="#FEAF05"
android:strokeLineCap="round"/>
<path
android:pathData="M13.865,19.125L13.865,9.51"
android:strokeWidth="2.2677"
android:fillColor="#00000000"
android:strokeColor="#FEAF05"
android:strokeLineCap="round"/>
<path
android:pathData="M17.938,19.125L17.938,4.594"
android:strokeWidth="2.2677"
android:fillColor="#00000000"
android:strokeColor="#FEAF05"
android:strokeLineCap="round"/>
</vector>

View file

@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#72a8ff"
android:fillColor="#007BB3"
android:pathData="M22,5.72l-4.6,-3.86 -1.29,1.53 4.6,3.86L22,5.72zM7.88,3.39L6.6,1.86 2,5.71l1.29,1.53 4.59,-3.85zM12.5,8L11,8v6l4.75,2.85 0.75,-1.23 -4,-2.37L12.5,8zM12,4c-4.97,0 -9,4.03 -9,9s4.02,9 9,9c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,20c-3.87,0 -7,-3.13 -7,-7s3.13,-7 7,-7 7,3.13 7,7 -3.13,7 -7,7z" />
</vector>

View file

@ -0,0 +1,5 @@
<vector android:height="48dp" android:viewportHeight="30.05"
android:viewportWidth="30.05" android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#BA4242" android:pathData="M18.993,10.688h-7.936c-0.19,0 -0.346,0.149 -0.346,0.342v8.022c0,0.189 0.155,0.344 0.346,0.344h7.936c0.19,0 0.344,-0.154 0.344,-0.344V11.03C19.336,10.838 19.183,10.688 18.993,10.688z"/>
<path android:fillColor="#BA4242" android:pathData="M15.026,0C6.729,0 0.001,6.726 0.001,15.025S6.729,30.05 15.026,30.05c8.298,0 15.023,-6.726 15.023,-15.025S23.324,0 15.026,0zM15.026,27.54c-6.912,0 -12.516,-5.604 -12.516,-12.515c0,-6.914 5.604,-12.517 12.516,-12.517c6.913,0 12.514,5.603 12.514,12.517C27.54,21.936 21.939,27.54 15.026,27.54z"/>
</vector>

View file

@ -37,7 +37,6 @@
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
@ -82,10 +81,8 @@
android:textColor="@android:color/white"
android:textSize="14sp" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
@ -449,7 +446,6 @@
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
@ -729,7 +725,6 @@
android:layout_marginBottom="5dp"
android:background="@color/listdelimiter" />
</LinearLayout>
</ScrollView>
@ -752,7 +747,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:drawableTop="@drawable/ic_actions_refill"
android:drawableTop="@drawable/ic_refresh_pod_status"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:text="@string/omnipod_overview_button_refresh" />
@ -763,7 +758,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:drawableTop="@drawable/ic_danarhistory"
android:drawableTop="@drawable/ic_pod_management"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:text="@string/omnipod_overview_button_pod_management" />
@ -774,41 +769,18 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:drawableTop="@drawable/ic_cp_aaps_offline"
android:drawableTop="@drawable/ic_acknowledge_alerts"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:text="@string/omnipod_overview_button_acknowledge_active_alerts" />
<Button
android:id="@+id/omnipod_overview_button_rileylink_stats"
style="@style/ButtonSmallFontStyle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:drawableTop="@drawable/ic_danarstats"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:text="@string/omnipod_overview_button_riley_link_stats" />
<Button
android:id="@+id/omnipod_overview_button_pulse_log"
style="@style/ButtonSmallFontStyle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:drawableTop="@drawable/ic_cp_bolus_correction"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:text="@string/omnipod_overview_button_read_pulse_log"
android:visibility="gone" />
<Button
android:id="@+id/omnipod_overview_button_set_time"
style="@style/ButtonSmallFontStyle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:drawableTop="@drawable/ic_access_alarm"
android:drawableTop="@drawable/ic_set_time"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:text="@string/omnipod_overview_button_set_time"
@ -820,7 +792,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:drawableTop="@drawable/ic_local_activate"
android:drawableTop="@drawable/ic_resume_delivery"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:text="@string/omnipod_overview_button_resume_delivery"
@ -832,7 +804,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:drawableTop="@drawable/ic_loop_disabled"
android:drawableTop="@drawable/ic_suspend_delivery"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:text="@string/omnipod_overview_button_suspend_delivery"

View file

@ -62,7 +62,7 @@
android:layout_marginTop="20dp"
android:layout_marginRight="40dp"
android:layout_weight="0.5"
android:drawableTop="@drawable/ic_cp_pump_canula"
android:drawableTop="@drawable/ic_activate_pod"
android:text="@string/omnipod_pod_management_button_activate_pod"
android:textAllCaps="false" />
@ -75,7 +75,7 @@
android:layout_marginTop="20dp"
android:layout_marginRight="40dp"
android:layout_weight="0.5"
android:drawableTop="@drawable/ic_actions_temptarget"
android:drawableTop="@drawable/ic_deactivate_pod"
android:text="@string/omnipod_pod_management_button_deactivate_pod"
android:textAllCaps="false" />
@ -88,10 +88,37 @@
android:layout_marginTop="20dp"
android:layout_marginRight="40dp"
android:layout_weight="0.5"
android:drawableTop="@drawable/ic_toast_delete_confirm"
android:drawableTop="@drawable/ic_discard_pod"
android:text="@string/omnipod_pod_management_button_discard_pod"
android:textAllCaps="false" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/omnipod_pod_management_button_play_test_beep"
style="?android:attr/buttonStyle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="40dp"
android:layout_marginTop="20dp"
android:layout_marginRight="40dp"
android:layout_weight="0.5"
android:drawableTop="@drawable/ic_play_test_beep"
android:text="@string/omnipod_pod_management_button_play_test_beep"
android:textAllCaps="false" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/omnipod_pod_management_button_pulse_log"
style="?android:attr/buttonStyle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="40dp"
android:layout_marginTop="20dp"
android:layout_marginRight="40dp"
android:layout_weight="0.5"
android:drawableTop="@drawable/ic_pulse_log"
android:text="@string/omnipod_pod_management_button_read_pulse_log"
android:textAllCaps="false"
android:visibility="gone" />
<info.nightscout.androidaps.utils.ui.SingleClickButton
android:id="@+id/omnipod_pod_management_button_pod_history"
style="?android:attr/buttonStyle"
@ -101,10 +128,23 @@
android:layout_marginTop="20dp"
android:layout_marginRight="40dp"
android:layout_weight="0.5"
android:drawableTop="@drawable/ic_danarhistory"
android:drawableTop="@drawable/ic_pod_history"
android:text="@string/omnipod_pod_management_button_pod_history"
android:textAllCaps="false" />
<info.nightscout.androidaps.utils.ui.SingleClickButton
android:id="@+id/omnipod_pod_management_button_rileylink_stats"
style="?android:attr/buttonStyle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="40dp"
android:layout_marginTop="20dp"
android:layout_marginRight="40dp"
android:layout_weight="0.5"
android:drawableTop="@drawable/ic_rl_stats"
android:text="@string/omnipod_pod_management_button_riley_link_stats"
android:textAllCaps="false" />
</LinearLayout>
</ScrollView>

View file

@ -29,7 +29,7 @@
android:layout_gravity="center_horizontal"
android:layout_marginTop="@dimen/omnipod_wizard_vertical_spacing"
android:layout_marginBottom="@dimen/omnipod_wizard_vertical_spacing"
app:srcCompat="@drawable/ic_toast_check"
app:srcCompat="@drawable/ic_success"
android:visibility="gone" />
<TextView

View file

@ -10,6 +10,7 @@
<string name="key_omnipod_tbr_beeps_enabled" translatable="false">AAPS.Omnipod.tbr_beeps_enabled</string>
<string name="key_omnipod_suspend_delivery_button_enabled" translatable="false">AAPS.Omnipod.suspend_delivery_button_enabled</string>
<string name="key_omnipod_pulse_log_button_enabled" translatable="false">AAPS.Omnipod.pulse_log_button_enabled</string>
<string name="key_omnipod_rileylink_stats_button_enabled" translatable="false">AAPS.Omnipod.rileylink_stats_button_enabled</string>
<string name="key_omnipod_time_change_event_enabled" translatable="false">AAPS.Omnipod.time_change_enabled</string>
<string name="key_omnipod_expiration_reminder_enabled" translatable="false">AAPS.Omnipod.expiration_reminder_enabled</string>
<string name="key_omnipod_expiration_reminder_hours_before_shutdown" translatable="false">AAPS.Omnipod.expiration_reminder_hours_before_shutdown</string>
@ -39,8 +40,9 @@
<string name="omnipod_config_basal_beeps_enabled">Basal beeps enabled</string>
<string name="omnipod_config_smb_beeps_enabled">SMB beeps enabled</string>
<string name="omnipod_config_tbr_beeps_enabled">TBR beeps enabled</string>
<string name="omnipod_config_suspend_delivery_button_enabled">Suspend Delivery button enabled</string>
<string name="omnipod_config_pulse_log_button_enabled">Pulse Log button enabled</string>
<string name="omnipod_config_suspend_delivery_button_enabled">Show Suspend Delivery button in Omnipod tab</string>
<string name="omnipod_config_pulse_log_button_enabled">Show Pulse Log button in Pod Management menu</string>
<string name="omnipod_config_rileylink_stats_button_enabled">Show RileyLink Stats button in Pod Management menu</string>
<string name="omnipod_config_time_change_enabled">DST/Time zone detection enabled</string>
<string name="omnipod_config_expiration_reminder_enabled">Expiration reminder enabled</string>
<string name="omnipod_config_expiration_reminder_hours_before_shutdown">Hours before shutdown</string>
@ -122,6 +124,7 @@
<string name="omnipod_error_unknown_custom_command">Unknown custom command: %1$s</string>
<string name="omnipod_error_failed_to_read_pulse_log">Failed to read Pulse Log</string>
<string name="omnipod_error_failed_to_refresh_status">Failed to refresh status</string>
<string name="omnipod_error_failed_to_refresh_status_on_startup">Failed to refresh status on startup</string>
<string name="omnipod_error_failed_to_acknowledge_alerts">Failed to acknowledge alerts</string>
<string name="omnipod_error_failed_to_suspend_delivery">Failed to suspend delivery</string>
<string name="omnipod_error_failed_to_set_time">Failed to set time</string>
@ -135,6 +138,8 @@
<string name="omnipod_error_pod_fault_activation_time_exceeded">The Pod\'s activation time has been exceeded. This Pod can no longer be activated.</string>
<string name="omnipod_error_failed_to_verify_activation_progress">Failed to verify activation progress. Please retry.</string>
<string name="omnipod_error_pod_suspended">Pod suspended</string>
<string name="omnipod_error_failed_to_play_test_beep">Failed to play test beep</string>
<string name="omnipod_error_tbr_running_but_aaps_not_aware">A temporary basal is running on the Pod, but AAPS is unaware of this temporary basal. Please cancel your temporary basal manually.</string>
<!-- Omnipod - Confirmation -->
<string name="omnipod_confirmation">Confirmation</string>
@ -167,6 +172,8 @@
<string name="omnipod_cmd_read_pulse_log">Read pulse log</string>
<string name="omnipod_cmd_set_fake_suspended_tbr">Set fake temporary basal because the Pod is suspended</string>
<string name="omnipod_cmd_cancel_fake_suspended_tbr">Cancel fake temporary basal that was created because the Pod was suspended</string>
<string name="omnipod_cmd_beep_config">Beep config</string>
<string name="omnipod_cmd_play_test_beep">Play test beep</string>
<!-- Omnipod - Pod Management -->
<string name="omnipod_pod_management_title">Pod management</string>
@ -175,7 +182,12 @@
<string name="omnipod_pod_management_button_deactivate_pod">Deactivate Pod</string>
<string name="omnipod_pod_management_button_discard_pod">Discard Pod</string>
<string name="omnipod_pod_management_button_pod_history">Pod history</string>
<string name="omnipod_pod_management_discard_pod_state_confirmation">If you discard the Pod, you will not be able to communicate with it anymore. You should only do this when all communication with the Pod persistently fails. If you can still communicate with the Pod, please use the <b>Deactivate Pod</b> option.\n\nIf you wish to proceed, please make sure to remove the Pod from your body!</string>
<string name="omnipod_pod_management_button_riley_link_stats">RileyLink stats</string>
<string name="omnipod_pod_management_button_read_pulse_log">Read pulse log</string>
<string name="omnipod_pod_management_button_reading_pulse_log">Reading pulse log…</string>
<string name="omnipod_pod_management_discard_pod_confirmation">If you discard the Pod, you will not be able to communicate with it anymore. You should only do this when all communication with the Pod persistently fails. If you can still communicate with the Pod, please use the <b>Deactivate Pod</b> option.\n\nIf you wish to proceed, please make sure to remove the Pod from your body!</string>
<string name="omnipod_pod_management_button_play_test_beep">Play test beep</string>
<string name="omnipod_pod_management_button_playing_test_beep">Playing test beep…</string>
<!-- Omnipod - Wizard common -->
<string name="omnipod_wizard_button_cancel">Cancel</string>
@ -215,8 +227,6 @@
<!-- Omnipod - Overview -->
<string name="omnipod_overview_button_set_time">Set time</string>
<string name="omnipod_overview_button_suspend_delivery">Suspend</string>
<string name="omnipod_overview_button_riley_link_stats">RL stats</string>
<string name="omnipod_overview_button_read_pulse_log">Pulse log</string>
<string name="omnipod_overview_button_refresh">Refresh</string>
<string name="omnipod_overview_button_resume_delivery">Resume delivery</string>
<string name="omnipod_overview_button_pod_management">Pod mgmt</string>

View file

@ -32,7 +32,7 @@
android:title="@string/omnipod_config_smb_beeps_enabled" />
<SwitchPreference
android:defaultValue="true"
android:defaultValue="false"
android:key="@string/key_omnipod_tbr_beeps_enabled"
android:title="@string/omnipod_config_tbr_beeps_enabled" />
@ -110,6 +110,11 @@
android:key="@string/key_omnipod_pulse_log_button_enabled"
android:title="@string/omnipod_config_pulse_log_button_enabled" />
<SwitchPreference
android:defaultValue="false"
android:key="@string/key_omnipod_rileylink_stats_button_enabled"
android:title="@string/omnipod_config_rileylink_stats_button_enabled" />
<SwitchPreference
android:defaultValue="true"
android:key="@string/key_omnipod_time_change_event_enabled"