diff --git a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java index d96fda8d3b..ec777aed25 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java +++ b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java @@ -425,7 +425,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { } - private void scheduleBgHistoryChange(@Nullable final long timestamp) { + private void scheduleBgHistoryChange(@Nullable final long timestamp) { class PostRunnable implements Runnable { public void run() { aapsLogger.debug(LTag.DATABASE, "Firing EventNewBg"); @@ -440,8 +440,9 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { scheduledBgHistoryPost.cancel(false); Runnable task = new PostRunnable(); final int sec = 3; - if (oldestBgHistoryChange == 0 || oldestBgHistoryChange > timestamp) oldestBgHistoryChange = timestamp; - scheduledBgHistoryPost = bgHistoryWorker.schedule(task, sec, TimeUnit.SECONDS); + if (oldestBgHistoryChange == 0 || oldestBgHistoryChange > timestamp) + oldestBgHistoryChange = timestamp; + scheduledBgHistoryPost = bgHistoryWorker.schedule(task, sec, TimeUnit.SECONDS); } @@ -1871,7 +1872,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { } } - public List getAllOmnipodHistoryRecordsFromTimeStamp(long from, boolean ascending) { try { Dao daoPodHistory = getDaoPodHistory(); @@ -1890,6 +1890,20 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { return new ArrayList<>(); } + public OmnipodHistoryRecord findOmnipodHistoryRecordByPumpId(long pumpId) { + try { + Dao daoPodHistory = getDaoPodHistory(); + QueryBuilder queryBuilder = daoPodHistory.queryBuilder(); + queryBuilder.orderBy("date", false); + Where where = queryBuilder.where(); + where.eq("pumpId", pumpId); + PreparedQuery preparedQuery = queryBuilder.prepare(); + return daoPodHistory.queryForFirst(preparedQuery); + } catch (SQLException e) { + aapsLogger.error("Unhandled exception", e); + } + return null; + } // Copied from xDrip+ String calculateDirection(BgReading bgReading) { diff --git a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelperProvider.java b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelperProvider.java index 4468692189..ae3e52180c 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelperProvider.java +++ b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelperProvider.java @@ -3,6 +3,7 @@ package info.nightscout.androidaps.db; import com.j256.ormlite.dao.CloseableIterator; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.sql.SQLException; import java.util.List; @@ -99,6 +100,10 @@ public class DatabaseHelperProvider implements DatabaseHelperInterface { return MainApp.getDbHelper().getAllOmnipodHistoryRecordsFromTimeStamp(timestamp, ascending); } + @Nullable @Override public OmnipodHistoryRecord findOmnipodHistoryRecordByPumpId(long pumpId) { + return MainApp.getDbHelper().findOmnipodHistoryRecordByPumpId(pumpId); + } + @NotNull @Override public List getTDDsForLastXDays(int days) { return MainApp.getDbHelper().getTDDsForLastXDays(days); } diff --git a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppComponent.kt b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppComponent.kt index 345ab5a615..0c98864fb4 100644 --- a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppComponent.kt +++ b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppComponent.kt @@ -9,6 +9,8 @@ import info.nightscout.androidaps.core.di.CoreModule import info.nightscout.androidaps.dana.di.DanaModule import info.nightscout.androidaps.danar.di.DanaRModule import info.nightscout.androidaps.danars.di.DanaRSModule +import info.nightscout.androidaps.plugins.pump.common.dagger.RileyLinkModule +import info.nightscout.androidaps.plugins.pump.omnipod.dagger.OmnipodModule import javax.inject.Singleton @Singleton diff --git a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/FragmentsModule.kt b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/FragmentsModule.kt index cde5137ac9..ba077452fb 100644 --- a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/FragmentsModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/FragmentsModule.kt @@ -34,7 +34,7 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyL import info.nightscout.androidaps.plugins.pump.insight.LocalInsightFragment import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicFragment import info.nightscout.androidaps.plugins.pump.medtronic.dialog.RileyLinkStatusDeviceMedtronic -import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodFragment +import info.nightscout.androidaps.plugins.pump.omnipod.ui.OmnipodFragment import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpFragment import info.nightscout.androidaps.plugins.source.BGSourceFragment import info.nightscout.androidaps.plugins.treatments.TreatmentsFragment diff --git a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/OmnipodModule.kt b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/OmnipodModule.kt deleted file mode 100644 index e7a8f31cfa..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/OmnipodModule.kt +++ /dev/null @@ -1,50 +0,0 @@ -package info.nightscout.androidaps.dependencyInjection - -import dagger.Module -import dagger.Provides -import dagger.android.ContributesAndroidInjector -import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodPumpPlugin -import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager -import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.PodHistoryActivity -import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.PodManagementActivity -import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.initpod.InitActionFragment -import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.initpod.InitPodTask -import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.pages.InitPodRefreshAction -import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.pages.PodInfoFragment -import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.removepod.RemoveActionFragment -import info.nightscout.androidaps.plugins.pump.omnipod.driver.comm.AapsOmnipodManager -import info.nightscout.androidaps.plugins.pump.omnipod.driver.comm.AapsPodStateManager -import info.nightscout.androidaps.plugins.pump.omnipod.driver.ui.OmnipodUITask - -@Module -@Suppress("unused") -abstract class OmnipodModule { - - // Activities - @ContributesAndroidInjector - abstract fun contributesPodManagementActivity(): PodManagementActivity - @ContributesAndroidInjector abstract fun contributesPodHistoryActivity(): PodHistoryActivity - - // Fragments - @ContributesAndroidInjector abstract fun initActionFragment(): InitActionFragment - @ContributesAndroidInjector abstract fun removeActionFragment(): RemoveActionFragment - @ContributesAndroidInjector abstract fun podInfoFragment(): PodInfoFragment - - // Service - @ContributesAndroidInjector - abstract fun omnipodCommunicationManagerProvider(): OmnipodCommunicationManager - @ContributesAndroidInjector abstract fun aapsOmnipodManagerProvider(): AapsOmnipodManager - - // Data - @ContributesAndroidInjector abstract fun omnipodUITaskProvider(): OmnipodUITask - @ContributesAndroidInjector abstract fun initPodRefreshAction(): InitPodRefreshAction - @ContributesAndroidInjector abstract fun podStateManager(): PodStateManager - @ContributesAndroidInjector abstract fun initPodTask(): InitPodTask - @ContributesAndroidInjector abstract fun omnipodPumpPlugin(): OmnipodPumpPlugin - - companion object { - @Provides - fun podStateManagerProvider(aapsPodStateManager: AapsPodStateManager) : PodStateManager = aapsPodStateManager - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/ServicesModule.kt b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/ServicesModule.kt index f961c3a863..6ba01130ae 100644 --- a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/ServicesModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/ServicesModule.kt @@ -10,7 +10,7 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.Riley import info.nightscout.androidaps.plugins.pump.insight.InsightAlertService import info.nightscout.androidaps.plugins.pump.insight.connection_service.InsightConnectionService import info.nightscout.androidaps.plugins.pump.medtronic.service.RileyLinkMedtronicService -import info.nightscout.androidaps.plugins.pump.omnipod.service.RileyLinkOmnipodService +import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.service.RileyLinkOmnipodService import info.nightscout.androidaps.services.AlarmSoundService import info.nightscout.androidaps.services.DataService import info.nightscout.androidaps.services.LocationService diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/CareDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/CareDialog.kt index d52e3d26e6..bad46290aa 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/CareDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/CareDialog.kt @@ -156,9 +156,9 @@ class CareDialog : DialogFragmentWithDate() { if (options == EventType.BGCHECK || options == EventType.QUESTION || options == EventType.ANNOUNCEMENT) { val type = when { - actions_care_meter.isChecked -> "Finger" - actions_care_sensor.isChecked -> "Sensor" - else -> "Manual" + actions_care_meter.isChecked -> CareportalEvent.FINGER + actions_care_sensor.isChecked -> CareportalEvent.SENSOR + else -> CareportalEvent.MANUAL } actions.add(resourceHelper.gs(R.string.careportal_newnstreatment_glucosetype) + ": " + translator.translate(type)) actions.add(resourceHelper.gs(R.string.treatments_wizard_bg_label) + ": " + Profile.toCurrentUnitsString(profileFunction, actions_care_bg.value) + " " + resourceHelper.gs(unitResId)) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.java index ba01db465c..0040dbc6fc 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.java @@ -392,7 +392,7 @@ public class LoopPlugin extends PluginBase implements LoopInterface { } // Prepare for pumps using % basals - if (pump.getPumpDescription().tempBasalStyle == PumpDescription.PERCENT) { + if (pump.getPumpDescription().tempBasalStyle == PumpDescription.PERCENT && allowPercentage()) { result.usePercent = true; } result.percent = (int) (result.rate / profile.getBasal() * 100); @@ -650,7 +650,6 @@ public class LoopPlugin extends PluginBase implements LoopInterface { */ private void applyTBRRequest(APSResult request, Profile profile, Callback callback) { - boolean allowPercentage = virtualPumpPlugin.isEnabled(PluginType.PUMP); if (!request.tempBasalRequested) { if (callback != null) { @@ -681,7 +680,7 @@ public class LoopPlugin extends PluginBase implements LoopInterface { long now = System.currentTimeMillis(); TemporaryBasal activeTemp = treatmentsPlugin.getTempBasalFromHistory(now); - if (request.usePercent && allowPercentage) { + if (request.usePercent && allowPercentage()) { if (request.percent == 100 && request.duration == 0) { if (activeTemp != null) { getAapsLogger().debug(LTag.APS, "applyAPSRequest: cancelTempBasal()"); @@ -784,6 +783,10 @@ public class LoopPlugin extends PluginBase implements LoopInterface { commandQueue.bolus(detailedBolusInfo, callback); } + private boolean allowPercentage() { + return virtualPumpPlugin.isEnabled(PluginType.PUMP); + } + public void disconnectPump(int durationInMinutes, Profile profile) { PumpInterface pump = activePlugin.getActivePump(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt index 20a6493ea8..900b15bde6 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt @@ -25,7 +25,6 @@ import info.nightscout.androidaps.plugins.general.actions.defs.CustomAction import info.nightscout.androidaps.plugins.general.overview.StatusLightHandler import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.FabricPrivacy -import info.nightscout.androidaps.utils.ui.SingleClickButton import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.utils.extensions.plusAssign @@ -33,6 +32,7 @@ import info.nightscout.androidaps.utils.extensions.toVisibility import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.sharedPreferences.SP +import info.nightscout.androidaps.utils.ui.SingleClickButton import info.nightscout.androidaps.utils.ui.UIRunnable import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable @@ -236,6 +236,7 @@ class ActionsFragment : DaggerFragment() { actions_historybrowser.visibility = (profile != null).toVisibility() actions_fill?.visibility = (pump.pumpDescription.isRefillingCapable && pump.isInitialized && !pump.isSuspended).toVisibility() + actions_pumpbatterychange?.visibility = pump.pumpDescription.isBatteryReplaceable.toVisibility() actions_temptarget?.visibility = (profile != null && config.APS).toVisibility() actions_tddstats?.visibility = pump.pumpDescription.supportsTDDs.toVisibility() diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/messages/OpenDatasetRequestMessage.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/messages/OpenDatasetRequestMessage.kt index c0b0d3a92b..bc6e00f59a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/messages/OpenDatasetRequestMessage.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/messages/OpenDatasetRequestMessage.kt @@ -14,7 +14,7 @@ class OpenDatasetRequestMessage (val serialNumber : String): BaseMessage() { @Expose var deviceId: String = TidepoolUploader.PUMP_TYPE + ":" + serialNumber @Expose - var time = DateUtil.toISOAsUTC(DateUtil.now()) + var time: String = DateUtil.toISOAsUTC(DateUtil.now()) @Expose var timezoneOffset = (DateUtil.getTimeZoneOffsetMs() / T.mins(1).msecs()).toInt() @Expose @@ -23,7 +23,7 @@ class OpenDatasetRequestMessage (val serialNumber : String): BaseMessage() { @Expose var client = ClientInfo() @Expose - var computerTime = DateUtil.toISONoZone(DateUtil.now()) + var computerTime: String = DateUtil.toISONoZone(DateUtil.now()) @Expose var dataSetType = "continuous" @Expose @@ -37,7 +37,7 @@ class OpenDatasetRequestMessage (val serialNumber : String): BaseMessage() { @Expose var timeProcessing = "none" @Expose - var timezone = TimeZone.getDefault().id + var timezone: String = TimeZone.getDefault().id @Expose var version = BuildConfig.VERSION_NAME diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/insulin/ActivityGraph.java b/app/src/main/java/info/nightscout/androidaps/plugins/insulin/ActivityGraph.java index cb8dabdde5..ee682272a1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/insulin/ActivityGraph.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/insulin/ActivityGraph.java @@ -49,8 +49,8 @@ public class ActivityGraph extends GraphView { for (long time = 0; time <= hours * 60 * 60 * 1000; time += 5 * 60 * 1000L) { Iob iob = t.iobCalc(time, dia); - activityArray.add(new DataPoint(time / 60 / 1000, iob.activityContrib)); - iobArray.add(new DataPoint(time / 60 / 1000, iob.iobContrib)); + activityArray.add(new DataPoint(time / 60.0 / 1000, iob.activityContrib)); + iobArray.add(new DataPoint(time / 60.0 / 1000, iob.iobContrib)); } DataPoint[] activityDataPoints = new DataPoint[activityArray.size()]; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/mdi/MDIPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/mdi/MDIPlugin.java index 44550ebea6..dbc8823395 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/mdi/MDIPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/mdi/MDIPlugin.java @@ -11,7 +11,6 @@ import javax.inject.Inject; import javax.inject.Singleton; import dagger.android.HasAndroidInjector; -import info.nightscout.androidaps.BuildConfig; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.Profile; @@ -69,6 +68,7 @@ public class MDIPlugin extends PumpPluginBase implements PumpInterface { pumpDescription.isTempBasalCapable = false; pumpDescription.isSetBasalProfileCapable = false; pumpDescription.isRefillingCapable = false; + pumpDescription.isBatteryReplaceable = false; } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityAAPSPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityAAPSPlugin.java index 9f81d9306e..7e1ff541dd 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityAAPSPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityAAPSPlugin.java @@ -155,7 +155,7 @@ public class SensitivityAAPSPlugin extends AbstractSensitivityPlugin { Arrays.sort(deviations); double percentile = IobCobCalculatorPlugin.percentile(deviations, 0.50); - double basalOff = percentile * (60 / 5) / sens; + double basalOff = percentile * (60.0 / 5.0) / sens; double ratio = 1 + (basalOff / profile.getMaxDailyBasal()); if (percentile < 0) { // sensitive diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityWeightedAveragePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityWeightedAveragePlugin.java index 27b1820735..d38489ea3b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityWeightedAveragePlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/sensitivity/SensitivityWeightedAveragePlugin.java @@ -159,7 +159,7 @@ public class SensitivityWeightedAveragePlugin extends AbstractSensitivityPlugin for (int i = 0; i < data.size(); i++) { long reversedWeigth = data.keyAt(i); double value = data.valueAt(i); - double weight = (hightestWeight - reversedWeigth) / 2; + double weight = (hightestWeight - reversedWeigth) / 2.0; weights += weight; weightedsum += weight * value; } diff --git a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandStartPump.kt b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandStartPump.kt index da911775bf..aaed20bf7f 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandStartPump.kt +++ b/app/src/main/java/info/nightscout/androidaps/queue/commands/CommandStartPump.kt @@ -2,6 +2,8 @@ package info.nightscout.androidaps.queue.commands import dagger.android.HasAndroidInjector import info.nightscout.androidaps.interfaces.ActivePluginProvider +import info.nightscout.androidaps.interfaces.ProfileFunction +import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin import info.nightscout.androidaps.queue.Callback import javax.inject.Inject @@ -12,12 +14,19 @@ class CommandStartPump( ) : Command(injector, CommandType.START_PUMP, callback) { @Inject lateinit var activePlugin: ActivePluginProvider + @Inject lateinit var profileFunction: ProfileFunction override fun execute() { val pump = activePlugin.activePump if (pump is LocalInsightPlugin) { val result = pump.startPump() callback?.result(result)?.run() + } else if (pump.pumpDescription.pumpType == PumpType.Insulet_Omnipod) { + // When using CommandQueue.setProfile, it refuses to set the profile is the same as the current profile + // However we need to set the current profile to resume delivery in case the Pod is suspended + if (profileFunction.getProfile() != null) { + pump.setNewBasalProfile(profileFunction.getProfile()) + } } } diff --git a/app/src/main/java/info/nightscout/androidaps/utils/JSONFormatter.java b/app/src/main/java/info/nightscout/androidaps/utils/JSONFormatter.java index db1f6af239..d5e576b413 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/JSONFormatter.java +++ b/app/src/main/java/info/nightscout/androidaps/utils/JSONFormatter.java @@ -9,6 +9,9 @@ import org.json.JSONObject; import org.slf4j.Logger; import java.util.Iterator; +import java.util.Date; +import java.text.SimpleDateFormat; +import java.text.DateFormat; import info.nightscout.androidaps.logging.StacktraceLoggerWrapper; @@ -84,6 +87,7 @@ public class JSONFormatter { private String visit(final Object object, final int indent) throws JSONException { String ret = ""; + Long n; if (object instanceof JSONArray) { ret += visit((JSONArray) object, indent); } else if (object instanceof JSONObject) { @@ -92,7 +96,19 @@ public class JSONFormatter { if (object instanceof String) { ret += write("\"" + ((String) object).replace("<", "<").replace(">", ">") + "\"", indent); } else { - ret += write(String.valueOf(object), indent); + // try to detect Date as milliseconds + if (object instanceof Long) { + n = (Long) object; + if (n > 1580000000000L && n < 2000000000000L) { // from 2020.01.26 to 2033.05.18 it is with high probability a date object + Date date = new Date(n); + DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + ret += write(formatter.format(date), indent); + } else { + ret += write(String.valueOf(object), indent); + } + } else { + ret += write(String.valueOf(object), indent); + } } } return ret; @@ -107,4 +123,4 @@ public class JSONFormatter { return ret; } } -} \ No newline at end of file +} diff --git a/app/src/main/java/info/nightscout/androidaps/utils/LocalAlertUtils.kt b/app/src/main/java/info/nightscout/androidaps/utils/LocalAlertUtils.kt index 499fe8afa8..bf5b5504e8 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/LocalAlertUtils.kt +++ b/app/src/main/java/info/nightscout/androidaps/utils/LocalAlertUtils.kt @@ -1,6 +1,7 @@ package info.nightscout.androidaps.utils import info.nightscout.androidaps.Config +import info.nightscout.androidaps.Constants import info.nightscout.androidaps.R import info.nightscout.androidaps.db.BgReading import info.nightscout.androidaps.interfaces.ActivePluginProvider @@ -36,11 +37,11 @@ class LocalAlertUtils @Inject constructor( ) { fun missedReadingsThreshold(): Long { - return T.mins(sp.getInt(resourceHelper.gs(R.string.key_missed_bg_readings_threshold), 30).toLong()).msecs() + return T.mins(sp.getInt(resourceHelper.gs(R.string.key_missed_bg_readings_threshold_minutes), Constants.DEFAULT_MISSED_BG_READINGS_THRESHOLD_MINUTES).toLong()).msecs() } fun pumpUnreachableThreshold(): Long { - return T.mins(sp.getInt(resourceHelper.gs(R.string.key_pump_unreachable_threshold), 30).toLong()).msecs() + return T.mins(sp.getInt(resourceHelper.gs(R.string.key_pump_unreachable_threshold_minutes), Constants.DEFAULT_PUMP_UNREACHABLE_THRESHOLD_MINUTES).toLong()).msecs() } fun checkPumpUnreachableAlarm(lastConnection: Long, isStatusOutdated: Boolean, isDisconnected: Boolean) { diff --git a/app/src/main/java/info/nightscout/androidaps/utils/stats/TirCalculator.kt b/app/src/main/java/info/nightscout/androidaps/utils/stats/TirCalculator.kt index bbda132d80..2d65ddbdf2 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/stats/TirCalculator.kt +++ b/app/src/main/java/info/nightscout/androidaps/utils/stats/TirCalculator.kt @@ -76,7 +76,7 @@ class TirCalculator @Inject constructor( val tit30 = calculate(30, lowTitMgdl, highTitMgdl) val averageTit30 = averageTIR(tit30) return HtmlHelper.fromHtml( - "
" + resourceHelper.gs(R.string.tir) + ":
" + + "
" + resourceHelper.gs(R.string.tir) + " (" + Profile.toCurrentUnitsString(profileFunction, lowTirMgdl) + "-" + Profile.toCurrentUnitsString(profileFunction, highTirMgdl) + "):
" + toText(resourceHelper, tir7) + "
" + resourceHelper.gs(R.string.average) + " (" + Profile.toCurrentUnitsString(profileFunction, lowTirMgdl) + "-" + Profile.toCurrentUnitsString(profileFunction, highTirMgdl) + "):
" + averageTir7.toText(resourceHelper, tir7.size()) + "
" + diff --git a/app/src/main/res/layout/overview_fragment_nsclient_tablet.xml b/app/src/main/res/layout/overview_fragment_nsclient_tablet.xml index d546bddceb..e4b9da7bfd 100644 --- a/app/src/main/res/layout/overview_fragment_nsclient_tablet.xml +++ b/app/src/main/res/layout/overview_fragment_nsclient_tablet.xml @@ -44,17 +44,13 @@ android:textSize="90dp" android:textStyle="bold" /> - + android:paddingTop="18dp" + android:src="@drawable/ic_flat" /> Bolus slimjan min - - Nooit gekontak nie - Besig om te wek - Fout met kommunikasie - Te lank op kommunikasie gewag - Pomp onbeskikbaar - Ongeldige konfigirasie - Aktief - Slaap - - - - - - - - - diff --git a/app/src/main/res/values-bg-rBG/strings.xml b/app/src/main/res/values-bg-rBG/strings.xml index 2d2597a27a..9746325667 100644 --- a/app/src/main/res/values-bg-rBG/strings.xml +++ b/app/src/main/res/values-bg-rBG/strings.xml @@ -1082,7 +1082,6 @@ Изчисти приключение Изчисти стартираните Искате ли да нулирате прогреса си? - Време и/или промяна на часовата зона на помпата Не е избрана помпа Изберете единиците, в които искате да работите Качване на локални промени в НС профила @@ -1159,7 +1158,6 @@ Удостоверяването неуспешно Абсолютен инсулин Главната парола се използва за архивиране на настройки и за подмяна на защитата в приложението. Запомни я или я пази на сигурно място. - Паролите не съвпадат Сегашна главна парола Индикатори Копиране на настройки от NS @@ -1168,123 +1166,6 @@ Бутоните винаги се показват на дъното на екрана. Голям екран Тема - - Никога не сме се свързвали - Събуждане - Грешка в комуникацията - Изтичане на времето за връзка - Помпата е недостъпна - Грешна конфигурация - Активна - Спинка си - - - Интеграция на помпата Omnipod, изисква RileyLink устройство (с фърмуер минимум 2.0 ) . - - Звук при болус активен - Звук при базал активен - Звук при SMB активен - Звук при временен базал активен - Опции за отстраняване на грешки в под активирани - Разрешено е DST/Timezone - - Под Mgmt - Статус на под - %1$.2f Е остават - Над 50 Е - Адрес на под - Срокът на пода изтича - Няма информация. - Няма активен под - Под не е инициализиран - Сигнали за активен под - Ack Предупреждения - - Omnipod (433.91 MHz) - - Забранено действие.\n\n Първо трябва да конфигурурате Omnipod , преди да използвате тази операция,. - Операцията не е възможна.\n\n Трябва да изчакате няколко минути, докато AAPS се опита да зададе профил за първи път. - Неправилен PodInitActionType: %1$s - Няма активен под. - Грешка при проверка на командата - Непредвидена грешка. Моля, докладвайте! (тип: %1$s). - Неуспешна комуникация: получени грешни входни параметри. - Връзката е неуспешна: таймаут. - Комуникацията е неуспешна: възникнала е неочаквана грешка. Моля, докладвайте! - Неуспешна комуникация: проверката на целостта на съобщението е неуспешна. - Неуспешна комуникация: получени грешни входни параметри. - Съобщението е неуспешно: Pod е в лошо състояние. - Неуспешна комуникация: получени грешни входни параметри. - Неуспешна комуникация: получи съобщение с невалиден номер на последователност от Pod. - Неуспешна комуникация: получи съобщение с невалиден номер на последователност от Pod. - Неуспешна комуникация: получени грешни входни параметри. - Комуникацията е неуспешна: nonce ресинхронизирането е неуспешно. - Комуникацията е неуспешна: nonce ресинхронизирането е неуспешно. - Комуникацията е неуспешна: няма достатъчно данни, получени от Pod. - Грешка на Pod (%1$03d %2$s). Моля, деактивирайте вашия Pod и стартирайте нов. - Комуникацията е неуспешна: Pod върна отговор с грешка. - - Управление на Pod - Инициализация на Pod - Деактивирай под - Нулиране на под - История на под - Стартирай болус - Отмяна на болус - Приложи временен базал - Отказ на базал - Отказ на базал - Задаване на график за базал - Получу статус на под - Получи информация за Pod - Задаване на час - Конфигуриране на аларми - Потвърждение на аларми - Спиране на доставката на инсулин - Подновяване на доставката - Непознат запис - %1$.1fЕ - %1$.1f U, CH=%2$.1f g - Скорост: %1$.1f U, Продължителност: %2$d мин. - Ако натиснете OK, състоянието на Pod ще бъде нулирано и няма да можете да общувате с него повече. Правете това, само ако вече не можеш да се свързвате с него. Ако все още можете да общувате с Под, моля, използвайте опцията Деактивирай Pod. - Историята на Pod не е достъпна в момента. - Напълни Pod - \nНапълнете с достатъчно инсулин за 3 дни.\n\nИзчакайте два сигнала от Pod по време на процеса на зареждане. Те показват, че е вмъкнат минималният размер от 85U. Уверете се, че сте изпразнил напълно спринцовката, дори след като сте чули двата сигнала.\n\nСлед пълнене на Pod, моля натиснете Следващ.\n\nЗабележка: не вадете капачката на капсулата на Podв този момент. - Пълнене - Опитвам се да се сдвоя с Pod.\n\nКогато всички елементи са проверени, можете да натиснете Следващ.\n\nЗабележка: задръжте Pod много близо до RileyLink в този момент. - Прикрепете Pod - \nПодгответе мястото за инфузия. Отстранете капачката на Pod и лепенката и прикрепете капсулата към мястото за инфузия.\n\nАко канюла стърчи, моля натиснете Отказ и изхвърлете вашия Pod.\n\nПрес Следваща да се вмъкне канюлата и да започне базалната доставка. - Вмъкване на канюла - Опитвам се да определя първоначалния базален график и да вмъкна канюлата.\n\nКогато всички елементи са проверени, можете да натиснете Следващ. - Информация за Pod - \Podе активна.\n\nВашият базален график е програмиран и канюлата вмъкната.\n\nМоля, проверете дали канюлата е поставена правилно или заменете Pod, ако чувствате, че не е. - Деактивирай Pod - \nНатиснете Следващ , за да деактивирате Pod.\n\nЗабележка: Това ще спре всички доставки на инсулин и деактивира Pod. - Деактивиране на Pod - Деактивиране на Pod.\n\nКогато всички елементи са проверени, можете да натиснете Следващ.\n\nЗабележка: Ако деактивирането непрекъснато се проваля, моля натиснете Отказ и използвайте опция Нулирай Pod , за да възстановите състоянието на Pod. - Pod изключен.\n\nмоля, извадете Pod от тялото си и го хвърли. - Сдвояване на под - Пълнене на под - Напълни канула - Приложи базалният профил - Отмяна - Деактивирай под - - - Интеграция на Omnipod Dash. - Край на напомняне за сдвояване - Край на напомнянето за настройка - Подът скоро ще изтече - Подът скоро ще изтече - Спирането е неизбежно - Минимален инсулин в резервоара - Непозната аларма - Задаването на базален профил може да е неуспешно. Доставката на инсулин може да бъде спряна! Моля, опреснете статуса на под. - Стартиране на временен базал неуспешно. Ако е имало вече такъв, той може да е бил отменен! Моля, обновете статуса на пода. - Задаването на време може да е неуспешно. Доставката на инсулин може да бъде спряна! Моля, опреснете статуса на под. - Не може да се провери статус на болус. Моля, уверете се, че вашият под е стартирал болус или го отменете. - Статистика на RL - Pulse лог Сравняване на профили Профил съветник Профил по подразбиране diff --git a/app/src/main/res/values-cs-rCZ/strings.xml b/app/src/main/res/values-cs-rCZ/strings.xml index d5fece0d2b..2e0c6745a4 100644 --- a/app/src/main/res/values-cs-rCZ/strings.xml +++ b/app/src/main/res/values-cs-rCZ/strings.xml @@ -559,6 +559,7 @@ Pumpa nedostupná Chybějící glykémie Používat systémové notifikace pro výstrahy a oznámení + Postupně zvyšovat hlasitost výstrah a oznámení Místní výstrahy Výstraha při nedostupných glykémiích Výstraha při nedostupné pumpě @@ -1082,7 +1083,6 @@ Vymazat dokončeno Vymazat start Chcete resetovat začátek cíle? Můžete přijít o svůj pokrok. - Změna času a/nebo časové zóny pumpy Nevybrána žádná pumpa Vyberte jednotky, ve kterých chcete zobrazit hodnoty Odeslat změny lokálního profilu do NS @@ -1159,7 +1159,6 @@ Autorizace selhala Absolutní inzulin Hlavní heslo se používá pro šifrování zálohy a pro \"přebití\" zabezpečení v aplikaci. Dobře si ho zapamatujte nebo uložte na bezpečném místě. - Hesla se neshodují Aktuální hlavní heslo Stavové indikátory Zkopírovat nastavení z NS @@ -1168,123 +1167,6 @@ Tlačítka jsou vždy zobrazena v dolní části obrazovky Velký displej Vzhled - - Nikdy nekontaktováno - Probouzení - Chyba komunikace - Vypršel časový limit komunikace - Pumpa nedostupná - Neplatná konfigurace - Aktivní - Spící - - - Integrace pumpy pro Omnipod, vyžaduje zařízení RileyLink (s firmwarem alespoň 2.0). - - Pípnutí při bolusu povoleno - Pípnutí při bazálu povoleno - Pípnutí při SMB povoleno - Pípnutí při TBR povoleno - Možnosti ladění podu povoleny - Letní čas / Detekce časového pásma povoleny - - Správa Podu - Stav Podu - Zbývá %1$.2f U - Více než 50 U - Adresa Podu - Expirace Podu - Žádné info - Žádný Pod není připojen - Není inicializován - Výstrahy aktivního Podu - Potrvdit upozornění - - Omnipod (433,91 MHz) - - Operace není možná.\n\nNejdříve je nutné nakonfigurovat Omnipod, než bude možné tuto funkci použít. - Operace není možná.\n\n Je třeba několik minut počkat, dokud se AAPS nepokusí poprvé nastavit profil. - Neplatný atribut PodInitActionType: %1$s - Žádný aktivní Pod. - Ověření příkazu se nezdařilo. - Došlo k neočekávané chybě. Nahlaste ji! (typ: %1$s). - Komunikace selhala: byly přijaty neplatné vstupní parametry. - Komunikace selhala: časový limit vypršel. - Komunikace se nezdařila: došlo k neočekávané chybě. Prosím nahlašte! - Komunikace selhala: ověření integrity zprávy se nezdařilo. - Komunikace selhala: byly přijaty neplatné pakety z podu. - Komunikace selhala: Pod je v chybném stavu. - Komunikace selhala: byla přijata neplatná odezva z Podu. - Komunikace selhala: od Podu byla přijata zpráva s neplatným pořadovým číslem. - Komunikace selhala: od Podu byla přijata zpráva s neplatnou adresou. - Komunikace selhala: nepodařilo se dekódovat zprávu z Podu. - Komunikace selhala: opaková synchronizace hodnoty Nonce se nezdařila. - Komunikace selhala: hodnota Nonce nebyla synchronizována. - Komunikace selhala: nedostatek dat přijatých z Podu. - Byla zjištěna chyba Podu (%1$03d %2$s). Deaktivujte Pod a spusťte nový. - Komunikace selhala: Pod vrátil chybovou odezvu. - - Správa Podu - Inicializovat Pod - Deaktivovat Pod - Resetovat Pod - Historie Podu - Nastavit bolsu - Zrušit bolus - Nastavit dočasný bazál - Zrušit dočasný bazál (interně ovladačem) - Zrušit dočasný bazál (nuceně uživatelem) - Nastavit plán bazálu - Zjistit stav Podu - Zjistit informace o Podu - Nastavit čas - Konfigurovat výstrahy - Potvrdit výstrahy - Pozastavit dodávání inzulínu - Obnovit dodávání inzulínu - Neznámá položka - %1$.1f U - %1$.1f U, Sach=%2$.1f g - Rychlost: %1$.1f U, doba trvání: %2$d min - Pokud stisknete OK, stav Podu bude vynuceně resetován a již nebudete moci komunikovat s Podem. Udělejte to pouze v případě, že s Podem již nelze komunikovat. Pokud stále můžete komunikovat s Podem, použijte volbu Deaktivovat Pod. - Historie Podu není v daném okamžiku k dispozici. - Naplňte Pod - \nNaplňte nový Pod dostatkem inzulínu na 3 dny.\n\nSledujte dvě pípnutí z Podu během procesu plnění. Tyto ukazují, že minimální množství 85U bylo naplněno. Ujistěte se, že stříkačka je zcela vyprázdněná a to i po vyslechnutí dvou pípnutí.\n\nPo naplnění Podu, prosím, stiskněte Další.\n\nPoznámka: prozatím nesundavejte kryt jehly. - Plnění - Snažím se spárovat s novým Podem a naplnit ho.\n\nJakmile budou zaškrtnuty všechny položky, můžete stisknout Další.\n\nPoznámka: ponechte prosím Pod velmi blízko RileyLinku. - Nasaďte Pod - \nPřipravte infuzní místo. Odstraňte krytku jehly a náplasti a nalepte Pod.\n\nPokud se kanyla odlepí, stiskněte Zrušit a zahoďte Pod.\n\nStiskněte Další pro vložení kanyly a spuštění bazálů. - Vkládání kanyly - Snažím se nastavit počáteční základní bazální plán a vložit kanylu.\n\nPři zaškrtnutí všech položek můžete stisknout tlačítko Další. - Pod Info - \nPod je nyní aktivní.\n\nVáš bazál byl naprogramován a kanyla byla vložena.\n\nOvěřte, prosím, že kanyla byla vložena správně a případně vyměňte Pod. - Deaktivovat Pod - \nStiskněte Další pro deaktivaci Podu.\n\nPoznámka: Zastavíte veškerý výdej inzulínu a deaktivujete Pod. - Deaktivace Podu - Deaktivace Podu.\n\nKdyž jsou zaškrtnuty všechny položky, můžete stisknout Další.\n\nPoznámka: Pokud deaktivace nepřetržitě selhává, prosím stiskněte Zrušit a použijte možnost Resetovat Pod pro resetování stavu Podu. - Pod deaktivován.\n\nOdstraňte Pod z těla a znehodnoťte jej. - Párování Podu - Plnění Podu - Plnění kanyly - Nastavit bazální profil - Zrušit podávání - Deaktivovat Pod - - - Integrace pumpy pro Omnipod Dash. - Upomínka dokončení párování - Upomínka dokončení nastavení - Životnost Podu brzy skončí - Pod brzy vyprší - Blíží se vypnutí - Nízký stav zásobníku - Neznámá výstraha - Nastavení bazálního profilu se možná nezdařilo. Výdej může být pozastaven! Obnovte prosím stav Podu. - Nastavení dočasného bazálu mohlo být neúspěšné. Pokud je dočasný bazál již spuštěn, mohl by být zrušen! Aktualizujte prosím stav Podu. - Nastavení času se možná nezdařilo. Výdej může být pozastaven! Obnovte prosím stav Podu. - Nelze ověřit, zda byl bolus úspěšný. Ověřte prosím, zda Váš Pod dodává bolus nebo ho zrušte. - Statistika RL - Pulse Log Porovnat profily Pomocník s profilem Výchozí profil diff --git a/app/src/main/res/values-de-rDE/strings.xml b/app/src/main/res/values-de-rDE/strings.xml index 14a8b8f2a5..957f3574c0 100644 --- a/app/src/main/res/values-de-rDE/strings.xml +++ b/app/src/main/res/values-de-rDE/strings.xml @@ -400,7 +400,7 @@ Zeige detailliertes IOB Differenziere IOB in Bolus- und Basal-IOB auf dem Watchface Nicht erfolgreich - bitte Telefon prüfen - nicht verfügbar + n/a Patientenalter Kind Teenager @@ -559,6 +559,7 @@ Pumpe ist nicht erreichbar BZ-Werte fehlen Benutze Systemmeldungen für Alarme und Meldungen + Passe die Lautstärke für Alarme und Hinweise etwas an. Lokale Alarme Alarm, wenn keine Glukose-Daten empfangen werden Alarm, wenn die Pumpe nicht erreichbar ist @@ -1083,7 +1084,6 @@ Unerwartetes Verhalten. Ziel erneut öffnen Ziel neu starten Möchtest Du den Start der Ziele zurücksetzen? Du verlierst Deine Fortschritte. - Zeit- und/oder Zeitzonenänderung an der Pumpe Keine Pumpe ausgewählt Wähle die Einheit, in der die Werte angezeigt werden sollen. Lade die Änderungen des lokalen Profils zu NS hoch. @@ -1160,7 +1160,6 @@ Unerwartetes Verhalten. Autorisierung fehlgeschlagen Gesamtinsulin Das Master-Passwort wird für die Backup-Verschlüsselung und zur Außerkraftsetzung der Sicherheit in der Anwendung verwendet. Merke es Dir oder bewahre es an einem sicheren Ort auf. - Die Passwörter stimmen nicht überein. Aktuelles Master-Passwort Statusanzeige Einstellung aus NS kopieren @@ -1169,124 +1168,6 @@ Unerwartetes Verhalten. Schaltflächen werden immer am unteren Rand des Bildschirms angezeigt Großer Bildschirm Erscheinungsbild - - Nie verbunden - Aufwecken - Fehler bei der Kommunikation - Zeitüberschreitung bei Kommunikation - Pumpe ist nicht erreichbar - Ungültige Einstellung - Aktiv - Schläft - - - Um den Omnipod nutzen zu können, brauchst Du einen RileyLink (mind. Firmware 2.0). - - Bolus-Piep aktiviert - Basal-Piep aktiviert - SMB-Piep aktiviert - TBR-Piep aktiviert - Pod-Debugging-Optionen aktiviert - Sommerzeit/Zeitzonen-Erkennung aktiviert - - Pod Mgmt - Pod Status - %1$.2f IE übrig - über 50 IE - Pod Adresse - Pod läuft ab - Keine Info - Kein Pod verbunden - Nicht initialisiert - Aktive Pod-Warnungen - Alarm bestätigen - - Omnipod (433.91 MHz) - - Aktion ist nicht möglich.\n\n Du musst zuerst den Omnipod konfigurieren, bevor Du diese Operation verwenden kannst. - Aktion ist nicht möglich.\n\n Du musst ein paar Minuten warten bis AAPS versucht, das Profil zum ersten Mal zu setzen. - Illegal PodInitActionType: %1$s - Kein aktiver Pod. - Kommandoprüfung fehlgeschlagen - Es ist ein unerwarteter Fehler aufgetreten. Bitte melden! (Typ: %1$s). - Kommunikation fehlgeschlagen: Ungültige Eingabeparameter empfangen. - Keine Verbindung: Zeitüberschreitung - Keine Verbindung: Es ist ein unerwarteter Fehler aufgetreten. Bitte melden! - Kommunikation fehlgeschlagen: Die Überprüfung der Nachrichtenintegrität ist fehlgeschlagen. - Kommunikation fehlgeschlagen: Es wurde ein ungültiges Paket vom Pod empfangen. - Kommunikation fehlgeschlagen: Der Pod befindet sich in einem falschen Status. - Kommunikation fehlgeschlagen: Es wurde eine ungültige Antwort vom Pod empfangen. - Kommunikation fehlgeschlagen: Ungültige Zeichenfolge vom Pod empfangen. - Kommunikation fehlgeschlagen: Ungültige Adresse vom Pod empfangen. - Kommunikation fehlgeschlagen: Nachricht vom Pod konnte nicht decodiert werden. - Kommunikation fehlgeschlagen: Nonce resync fehlgeschlagen. - Kommunikation fehlgeschlagen: Nonce nicht synchronisiert - Kommunikation fehlgeschlagen: Nicht genügend Daten vom Pod empfangen. - Ein Pod-Fehler (%1$03d %2$s) wurde festgestellt. Bitte deaktiviere den Pod und starte einen neuen. - Kommunikation fehlgeschlagen: Fehlerhafte Antwort vom Pod. - - Pod Management - Init Pod - Pod deaktivieren - Pod zurücksetzen - Pod Historie - Setze Bolus - Bolus abbrechen - Setze Temporäre Basalrate - Temporäre Basalrate abbrechen (intern über den Treiber) - Temporäre Basalrate abbrechen (vom Benutzer erzwungen) - Basalrate festlegen - Pod-Status abrufen - Pod-Info abrufen - Zeit einstellen - Warnungen konfigurieren - Alarme bestätigen - Abgabe abbrechen - Abgabe wieder aufnehmen - Unbekannte Eingabe - %1$.1f IE - %1$.1f IE, CH=%2$.1f g - Rate: %1$.1f IE, Dauer: %2$d min - Wenn Du OK klickst, wird die Verbindung zum Pod zwangsweise getrennt und Du wirst Dich nicht mehr mit ihm verbinden können. -Mache das nur, wenn AAPS nicht mehr mit dem Pod kommunizieren kann. Wenn dies noch geht, nutze stattdessen die Option Deaktiviere Pod. - Pod Historie derzeit nicht verfügbar. - Befülle den Pod - \nBefülle den neuen Pod mit ausreichend Insulin für 3 Tage.\n\nAchte auch zwei Pieptöne vom Pod während des Füllens. Diese zeigen an, dass der Pod mit der Mindestmenge von 85 IE befüllt wurde. Leere die Spritze komplett, auch wenn Du die beiden Pieptöne gehört hast.\n\nKlicke Weiter nachdem Du den Pod befüllt hast.\n\nHinweis: Entferne den Nadelschutz des Pods noch nicht. - Befüllen - Versuche Dich mit dem neuen Pod zu verbinden und befülle ihn.\n\nWenn alle Anzeigen angehakt sind, kannst Du Weiter klicken.\n\nHinweis: Pod und RileyLink müssen dabei sehr nah beieinander sein. - Befestige den Pod - \nBereite die Infusionsstelle vor. Entferne den Nadelschutz des Pods und die Schutzfolie über dem Kleber. Klebe dann den Pod an die gewünschte Körperstelle.\n\nFalls die Kanüle herausragt, klicke Abbrechen und verwirf den Pod.\n\nKlicke Weiter; um die Kanüle zu setzen und die Insulinabgabe zu beginnen. - Kanüle setzen - Erste Basalrate und Kanüle werden nun gesetzt.\n\nWenn alle Häkchen gesetzt sind, kannst Du Weiter klicken. - Pod Info - \nDer Pod ist jetzt aktiv.\n\nDeine Basalrate ist programmiert und die Kanüle wurde gesetzt.\n\nBitte überprüfe, ob die Kanüle korrekt gesetzt wurde und ersetze den Pod, wenn Du das Gefühl hast, dass dies nicht erfolgreich war. - Pod deaktivieren - \nDrücke Weiter um den Pod zu deaktivieren.\n\nHinweis: Dies unterbricht die gesamte Insulinabgabe und deaktiviert den Pod. - Deaktiviere den Pod - Deaktiviere den Pod.\n\nWenn alle Häkchen gesetzt sind, kannst Du Weiterdrücken.\n\nHinweis: Wenn das Deaktivieren fortwährend fehlschlägt, drücke bitte Abbrechen und verwende die Option Reset Pod, um den Pod Status zwangsweise zurückzusetzen. - Pod deaktiviert.\n\nBitte entferne den Pod von Deinem Körper und entsorge ihn. - Pod verbinden - Pod befüllen - Kanüle befüllen - Basalprofil setzen - Abgabe abbrechen - Pod deaktivieren - - - Integration für Omnipod Dash. - Erinnerung Kopplung beendet - Erinnerung Setup beendet - Pod läuft in Kürze ab - Pod läuft in Kürze ab - Herunterfahren steht unmittelbar bevor - Niedriger Reservoirstand - Unbekannter Alarm - Das Festlegen der Basalrate evtl. fehlgeschlagen. Insulinabgabe wird evtl. ausgesetzt! Aktualisiere den Pod-Status. - Das Festlegen der temporären Basalrate evtl. fehlgeschlagen. Sofern eine temporäre Basalrate bestand, wurde diese ggf. beendet! Aktualisiere den Pod-Status. - Das Festlegen der Zeit evtl. fehlgeschlagen. Insulinabgabe wird evtl. ausgesetzt! Aktualisiere den Pod-Status. - Erfolgreiche Bolusabgabe konnte nicht sicher ermittelt werden. Stelle sicher, dass der Pod Insulin abgibt oder brich den Bolus ab. - RL Stats - Pulse Log Profile vergleichen Profil-Helfer Standard-Profil diff --git a/app/src/main/res/values-el-rGR/strings.xml b/app/src/main/res/values-el-rGR/strings.xml index 3520b90a0c..cd6f51b85b 100644 --- a/app/src/main/res/values-el-rGR/strings.xml +++ b/app/src/main/res/values-el-rGR/strings.xml @@ -916,22 +916,4 @@ Οδηγός Bolus min - - Ποτέ δεν επικοινωνήσατε - Ξύπνημα - Σφάλμα με επικοινωνία - Λήξη χρόνου επικοινωνίας - Η αντλία δεν είναι διαθέσιμη - Μη έγκυρη παραμετροποίηση - Ενεργή - Sleeping - - - - - - - - - diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml index ebc478e5fd..c5a874037a 100644 --- a/app/src/main/res/values-es-rES/strings.xml +++ b/app/src/main/res/values-es-rES/strings.xml @@ -156,6 +156,7 @@ Basal Temporal Bolo extendido Nightscout versión: + Falta %1$d g Preferencias exportadas Exportar ajustes a Importar configuración de @@ -171,6 +172,8 @@ Se le solicitará la contraseña maestra, que es necesaria para descifrar las preferencias importadas. ¡Exportación cancelada! ¡Las preferencias NO se han exportado! ¡Importación cancelada! ¡Las preferencias NO se han importado! + ¡No se pueden importar preferencias! + Por favor, vuelve a la pantalla principal e inténtalo de nuevo. Seleccionar fichero para importar Por favor, compruebe las preferencias antes de importar: ¡Las preferencias no se pueden importar! @@ -232,6 +235,10 @@ Número mínimo de minutos que deben transcursar entre un bolus remoto y el siguiente Cuántos minutos deben transcurrir, al menos, entre un bolo y el siguiente Por su seguridad, para editar esta preferencia es necesario añadir al menos 2 números de teléfono. + Bolo %1$.2fU enviado correctamente + Entregando %1$.2f U + Bolo %1$.2fU enviado correctamente + Bolo de comida %1$.2f U entregado con éxito Objetivo %1$s para %2$d minutos Objetivo %1$s para %2$d minutos establecido correctamente Objetivo temporal cancelado con éxito @@ -255,7 +262,9 @@ Bomba reconectada Comando remoto no permitido El bolo remoto no está disponible. Inténtalo de nuevo más tarde. + Para iniciar una basal de %1$.2fU/h durante %2$d min, responder con el código %3$s Para cambiar el perfil a %1$s %2$d%% responder con el código %3$s + Para iniciar un bolo extendido de %1$.2fU durante %2$d minutos, responder con el código %3$s Para introducir %1$dg en %2$s responder con código %3$s Para iniciar una basal de %1$d%% durante %2$d min, responder con el código %3$s Para cancelar lazo por %1$d minutos responde con código %2$s @@ -264,6 +273,7 @@ Para desactivar el lazo responder con código %1$s Basal temporal %1$.2fU/h para %2$d min iniciada correctamente Bolo ampliado de %1$.2fU durante %2$d min se inició correctamente + Carbohidratos %1$d g ingresados correctamente Error al introducir %1$dg de carbohidratos Basal temporal de %1$d%% durante %2$d min iniciada correctamente Fallo inicio basal temporal @@ -637,6 +647,7 @@ Habilitar SMB con Objetivos Temporales Habilitar SMB cuando hay un Objetivo Temporal (TT) activo (ComerPronto, Actividad) Habilitar SMB con Objetivo Temporal Alto + Habilitar SMB cuando hay un objetivo temporal alto activo (ejercicio, superior a 100 mg/dl o 5.5 mmol/l) Insulina Carbohidratos Botones @@ -670,6 +681,7 @@ No administrar Bolo, solo anotar Categoría Subcategoría + Bolo sólo se registrará (no será entregado por la bomba) Rellenar BGs perdidos desde NS SMB administrado por bomba Actividad @@ -786,6 +798,7 @@ Pedir permiso La aplicación necesita permiso de ventana del sistema para las notificaciones La aplicación necesita permiso de ubicación para la exploración de BT e identificación de WiFi + La aplicación necesita permiso de almacenamiento para poder almacenar archivos de registro y valores de exportación Solicitar Configurar complemento de insulina Salir @@ -841,6 +854,7 @@ ¿Coinciden los códigos mostrados en este dispositivo y en su infusor? Insight sincronizada Accu-Chek Insight + %1$.2f U / %2$.2f U entregado %1$s: %2$s Tubo cambiado Hora del infusor actualizada @@ -898,6 +912,7 @@ Multionda: %1$.2f / %2$.2f U durante %3$d min Multionda: %1$.2f / %2$.2f U durante %3$d min TDD: %1$.2f + Reser.: %1$.2f U Batería.: %1$d%% Max. duración de recuperación [s] Min. duración de recuperación [s] @@ -1040,6 +1055,8 @@ Enviar a %1$s Enviar SMS a todos los números Mandar mensaje SMS + COB vs IOB + Restricción de bolo aplicada: %1$.2f U a %2$.2f U ! Se ha detectado una absorción lenta de hidratos de carbono: %2$d%% de tiempo. Compruebe de nuevo su calculo. Los COB se pueden sobrestimar, por lo que ¡se podría administrar más insulina de la cuenta!]]> Administrar esta parte del resultado del asistente de bolos [%] El asistente de bolos realiza el cálculo, pero solo se entrega esta parte de la insulina calculada. Útil con el algoritmo SMB. @@ -1065,7 +1082,6 @@ Limpieza finalizada Limpieza iniciada ¿Desea reiniciar el objetivo? Puedes perder tu progreso. - Cambio de hora y/o huso horario en la bomba Ninguna bomba seleccionada Seleccione las unidades en las que desea visualizar los valores Subir cambios de perfil local a NS @@ -1090,6 +1106,7 @@ Encuesta Entrada de edad no válida Peso no válido + Entrada % invalida %1$s: Low: %2$02d%% In: %3$02d%% High: %4$02d%%]]> Promedio TIR @@ -1141,7 +1158,6 @@ Ha fallado la autorización Insulina en total La contraseña maestra se usa para cifrar la copia de seguridad y para sustituir la seguridad en la aplicación. Recordar o almacenar en sitio seguro. - Contraseñas no coinciden Contraseña maestra actual Luces de estado Copiar ajustes de NS @@ -1150,128 +1166,15 @@ Los botones siempre se muestran en la parte inferior de la pantalla Pantalla grande Tema - - Nunca conectados - En fase de inicio - Error con la comunicación - Tiempo de espera en la comunicación - Infusora no alcanzable - Configuración no válida - Activo - Suspendida - - - La integración de la bomba para Omnipod requiere el dispositivo RileyLink (con al menos 2,0 firmware). - - Aviso de bolo activado - Aviso de basal activado - Aviso de SMB activado - Aviso de TBT activado - Opciones de depuración de Pod habilitadas - Detección de DST/Timezone habilitada - - Pod Mgmt - Estado de Pod - %1$.2f U restantes - Más De 50 U - Dirección de Pod - Pod Caduca - Sin info - Sin Pod conectado - No Inicializado - Alertas de Pod activas - Alertas Ack - - Omnipod (433.91 MHz) - - La operación no es posible.\n\nDebe configurar Omnipod primero, antes de poder usar esta operación. - La operación no es posible.\n\n Necesitas esperar unos minutos, hasta que AAPS intente establecer el perfil por primera vez. - Ilegal PodInitActionType: %1$s - Ningún pod activo. - Falló la verificación del comando. - Error inesperado. Por favor, informe! (tipo: %1$s). - Comunicación fallida: se han recibido parámetros de entrada inválidos. - Comunicación fallida: tiempo de espera. - La comunicación ha fallado: error inesperado. ¡Por favor, Informe! - Comunicación fallida: falló la verificación de integridad del mensaje. - La comunicación ha fallado: se ha recibido un paquete no válido del Pod. - La comunicación ha fallado: el Pod está en un estado incorrecto. - La comunicación ha fallado: se ha recibido una respuesta no válida del Pod. - Ha fallado la comunicación: se ha recibido un mensaje con un número de secuencia no válido del Pod. - La comunicación ha fallado: se ha recibido un mensaje con una dirección no válida desde el Pod. - La comunicación ha fallado: no se ha podido descodificar el mensaje del Pod. - La comunicación ha fallado: nonce resync ha fallado. - Comunicación fallida: nonce no sincronizada. - La comunicación ha fallado: no se han recibido suficientes datos del Pod. - Un error de Pod (%1$03d %2$s) se ha detectado. Por favor, desactive su Pod e inicie uno nuevo. - La comunicación ha fallado: el Pod ha devuelto una respuesta de error. - - Administración de Pod - Iniciar Pod - Desactivar Pod - Restablecer Pod - Historial de Pod - Establecer Bolo - Cancelar Bolus - Establecer la basal temporal - Cancelar Basal Temporal (Internamente por controlador) - Cancelar Basal Temporal (forzado por el usuario) - Establecer Planificación Basal - Obtener estado de Pod - Obtener información de Pod - Establecer hora - Configurar alertas - Confirmar Alertas - Suspender la entrega - Reanudar la entrega - Entrada desconocida - %1$.1fU - %1$.1f U, CH=%2$.1f g - Tasa: %1$.1f U, Duración: %2$d min - Si pulsa OK, el estado de Pod se restablecerá por la fuerza y ya no podrá comunicarse con el Pod. Hágalo sólo si ya no puede comunicarse con el Pod. Si todavía puede comunicarse con el Pod, utilice la opción Desactivar Pod. - Historial del Pod no disponible en el momento. - Llenar el Pod - \nLlenar el nuevo Pod con suficiente insulina durante 3 días.\n\nEscucha dos pitidos del Pod durante el proceso de llenado. Esto indica que se ha insertado la cantidad mínima de 85U. Asegúrese de vaciar completamente la jeringa, incluso después de escuchar los dos pitidos.\n\nDespués de llenar el Pod, por favor pulse Next.\n\nNota: no retire el capuchón de la aguja del Pod en este momento. - Cebado - Intentando emparejar con el nuevo Pod y primarlo.\n\nCuando todos los elementos están marcados, puedes pulsar Siguiente.\n\nNota: por favor mantenga el Pod muy cerca del RileyLink en este momento. - Adherir el Pod - \nPreparar el sitio de infusión. Retire el capuchón de la aguja del Pod y el adhesivo y aplique el Pod al sitio de perfusión.\n\nSi la cánula se queda fuera, por favor presione Cancel y descarte su Pod.\n\nPress Next para insertar la cánula y comenzar la entrega basal. - Insertar cánula - Intentando establecer la programación basal inicial e insertar la cánula.\n\nCuando todos los elementos están marcados, puede pulsar Siguiente. - Pod Info - \nEl Pod ahora está activo.\n\nSu horario basal ha sido programado y la cánula ha sido insertada.\n\nPor favor, verifique que la cánula ha sido insertada correctamente y reemplace su Pod si usted siente que no lo ha hecho. - Desactivar Pod - \nPulsa Siguiente para desactivar el Pod.\n\nNota: Esto suspenderá toda la entrega insulina y desactivará el Pod. - Desactivando el Pod - Desactivando el Pod.\n\nCuando se comprueban todos los elementos, puede pulsar Next.\n\nNota: Si la desactivación falla, por favor pulse Cancelar y utilice la opción Restablecer Pod para restablecer por la fuerza el estado de Pod. - Pod desactivado.\n\nPor favor, retire el Pod de su cuerpo y desecharlo. - Emparejar Pod - Llenado de cánula del Pod - Llenar cánula - Establecer el perfil basal - Cancelar entrega - Desactivar Pod - - - Integración de la bomba para Omnipod Dash. - Finalizar recordatorio de emparejamiento - Recordatorio de configuración finalizado - Pod a punto de caducar - Pod a punto de caducar - El apagado es inminente - Reservorio bajo - Alerta desconocida - La configuración del perfil basal podría haber fallado. ¡La entrega podría ser suspendida! Por favor, actualiza el estado de Pod. - La configuración de basal temporal podría haber fallado. Si ya se está ejecutando una basal temporal, ¡puede que haya sido cancelada! Por favor, actualice el estado del pod. - Ajuste de la hora puede ser que haya fallado. La entrega puede ser suspendido! Por favor, actualizar estado de Pod. - No se puede verificar si el bolo ha sido exitoso. Por favor verifique que su Pod está poniendo bolo o cancele el bolo. - Estadísticas del RL - Registro de pulso Comparar perfiles Asistente de perfil + Perfil predeterminado Perfil actual Perfil disponible Tipo de perfil Edad: %1$.0f TDD: %2$.0f U + Edad: %1$.0f TDD: %2$.0f U %3$d%% Edad: %1$.0f Peso: %2$.0f kg + % de basal + Perfil DPV por defecto diff --git a/app/src/main/res/values-fr-rFR/strings.xml b/app/src/main/res/values-fr-rFR/strings.xml index 837a357cde..11a9776ae9 100644 --- a/app/src/main/res/values-fr-rFR/strings.xml +++ b/app/src/main/res/values-fr-rFR/strings.xml @@ -1083,7 +1083,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Refaire l\'objectif Suppression démarrée Voulez-vous réinitialiser le début de l\'objectif ? Vous risquez de perdre vos progrès. - Heure et/ou fuseau horaire changé sur la pompe Aucune pompe sélectionnée Sélectionnez les unités dans lesquelles vous souhaitez afficher les valeurs Remonter les modifications de profil local dans NS @@ -1160,7 +1159,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Echec de l\'authentification Insuline absolue Le mot de passe principal est utilisé pour crypter les sauvegardes et superviser la sécurité de l\'application. Rappelez-vous en ou stockez le en lieu sûr. - Les mots de passe ne correspondent pas Mot de passe principal actuel Voyants d\'état Copier les paramètres depuis NS @@ -1169,123 +1167,6 @@ L\'ENSEMBLE DES RISQUES LIÉS À LA QUALITÉ ET À LA PERFORMANCE DU PROGRAMME S Les boutons sont toujours affichés en bas de l\'écran Grand écran Thème - - Jamais contacté - Réveil en cours - Erreur de communication - Expiration du délai d\'attente en communication - Pompe hors de portée - Configuration non valable - Activé - En veille - - - L\'intégration de la pompe Omnipod nécessite un boitier RileyLink (avec au minimum un firmware 2.0). - - Bip Bolus Activé - Bip Basal Activé - Bip SMB activé - Bip DBT Activé - Options de débogage Pod activées - Changement de Zone/Heure Activé - - Pod - État du Pod - %1$.2f U restantes - Plus de 50 U - Adresse du Pod - Pod Expiré - Pas d\'infos - Pas de Pod Connecté - Non initialisé - Activer Alertes Pod - Valid Alert - - Omnipod (433.91 MHz) - - Operation impossible.\n\nVous devez d\'abord configurer l\'Omnipod pour pouvoir faire cette operation. - Operation impossible.\n\nVous devez attendre quelques minutes, jusqu\'à ce que AAPS tente de définir le profil pour la première fois. - type d\'action d\'init Pod non autorisée : %1$s - Pas de Pod Actif. - Échec de vérification de la commande. - Erreur inconnue. Veuillez signaler ! (type : %1$s). - Échec de communication : paramètres d\'entrées reçus invalides. - Échec de communication : délai expiré. - Échec de communication : Erreur inconnue. Veuillez signaler ! - Échec de communication : vérification de l\'intégrité du message échouée. - Échec de communication : paquet reçu du Pod invalide. - Échec de communication : état du Pod incorrect. - Échec de communication : réponse invalide reçue du Pod. - Échec de communication : message reçu du Pod avec un numéro de séquence invalide. - Échec de communication : message reçu du Pod avec une adresse invalide. - Échec de communication : échec du décodage du message reçu du Pod. - Échec de communication : resynchro nonce échouée. - Échec de communication : nonce non synchro. - Échec de communication : pas assez de données reçues du Pod. - Un défaut du Pod a été détecté (%1$03d %2$s). Veuillez désactiver votre Pod et en démarrer un nouveau. - Échec de communication : le Pod a renvoyé un message d\'erreur. - - Gestion Pod - Init Pod - Désactiver Pod - Réinit. Pod - Historique Pod - Définir Bolus - Annuler Bolus - Définir le Basal Temporaire - Basal Temp Annulée (en interne par le pilote) - Basal Temp Annulée (par l\'utilisateur) - Définir le schéma de basal - État du Pod - Infos du Pod - Régler L\'heure - Configurer les alertes - Valider les Alertes - Suspendre l\'injection - Pousuivre l\'injection - Entrée inconnue - %1$.1f U - %1$.1f U, Gluc=%2$.1f g - Débit : %1$.1f U, Durée : %2$d min - Si vous appuyez sur OK, le Pod sera réinitialisé et vous ne pourrez plus communiquer avec lui. Ne le faite que si vous ne pouvez plus communiquer avec le Pod. Si vous pouvez toujours communiquer avec lui, veuillez utiliser l\'option Désactiver Pod. - Historique Pod non disponible pour le moment. - Remplir le Pod - \nRemplir le nouveau Pod avec suffisamment d\'insuline pendant 3 jours.\n\nÉcoutez les deux bips du Pod pendant le processus de remplissage. Ils indiquent que la quantité minimale de 85U a été ajouté. Assurez-vous de vider complètement la seringue de remplissage, même après avoir entendu les deux bips.\n\nAprès avoir rempli le Pod, veuillez appuyer sur Suivant.\n\nRemarque : Ne retirez pas la protection de l\'aiguille du Pod pour le moment. - Amorçage - Tentative d\'appairage et d\'amorçage du nouveau Pod.\n\nQuand tous les items sont cochées, appuyez sur Suivant.\n\nRemarque : Veuillez maintenir le Pod tout près du RileyLink en ce moment. - Collez le Pod - \nPréparez le site d\'injection. Enlevez la protection de l\'aiguille et le support adhésif et collez le Pod sur le site d\'injection.\n\nSi la canule se colle, appuyez sur Annuler et jetez votre Pod.\n\nAppuyez sur Suivant pour insérer la canule et démarrer l\'injection de la basal. - Insertion canule - Tentative de définir le schéma de basal et d\'insertion de la canule.\n\nQuand tous les items sont cochés, appuyez sur Suivant. - Infos Pod - \nLe Pod est maintenant actif.\n\nVos débits de basal ont été programmés et la canule a été insérée.\n\nVeuillez verifier que la canule a été insérée correctement et remplacez votre Pod si vous pensez que ce n\'est pas le cas. - Désactiver Pod - \nAppuyez sur Suivant pour désactiver le Pod.\n\nRemarque : Cela suspendra l\'injection de l\'insuline et désactivera le Pod. - Désactivation du Pod - Désactivation du Pod.\n\nQuand tous les items sont cochés, appuyez sur Suivant.\n\nRemarque : Si la désactivation échoue en permanence, appuyez sur Annuler et utilisez l\'option Réinit. Pod pour réinitialiser l\'état du Pod. - Pod désactivé.\n\nVeuillez enlever le Pod de votre corps et le jeter. - Appairer le Pod - Amorcer le Pod - Remplir tubulure - Définir profil de basal - Annuler l\'injection - Désactiver Pod - - - Intégration de la pompe Omnipod Dash. - Rappel fin d\'appairage - Rappel fin de configuration - Le Pod expire bientôt - Le Pod expire bientôt - Arrêt imminent - Réservoir bas - Alerte inconnue - Le paramétrage du profil basal a peut-être échoué. L\'injection pourrait être suspendue ! Veuillez actualiser l\'état du pod. - Le réglage de la basal temp a peut-être échoué. S\'il y avait déjà un DBT en cours, cela a peut-être été annulé ! Veuillez actualiser le statut du pod. - Le paramétrage de l\'heure a peut-être échoué. L\'injection pourrait être suspendue ! Veuillez actualiser l\'état du pod. - Impossible de vérifier si le bolus a réussi. Vérifiez que votre Pod délivre le bolus ou annulez le bolus. - État RL - Enreg. Pulse Comparer les profils Assistant Profil Profil par défaut diff --git a/app/src/main/res/values-ga-rIE/strings.xml b/app/src/main/res/values-ga-rIE/strings.xml index 94dbab337b..8f12c9934a 100644 --- a/app/src/main/res/values-ga-rIE/strings.xml +++ b/app/src/main/res/values-ga-rIE/strings.xml @@ -17,14 +17,4 @@ PBAGE OAPS - - - - - - - - - - diff --git a/app/src/main/res/values-hr-rHR/strings.xml b/app/src/main/res/values-hr-rHR/strings.xml index 2578fce6a9..1ce4989b86 100644 --- a/app/src/main/res/values-hr-rHR/strings.xml +++ b/app/src/main/res/values-hr-rHR/strings.xml @@ -5,14 +5,4 @@ - - - - - - - - - - diff --git a/app/src/main/res/values-it-rIT/objectives.xml b/app/src/main/res/values-it-rIT/objectives.xml index ba4a3d013f..1eb4e508a1 100644 --- a/app/src/main/res/values-it-rIT/objectives.xml +++ b/app/src/main/res/values-it-rIT/objectives.xml @@ -44,7 +44,7 @@ Dai prova della tua conoscenza Studia e rispondi correttamente alle domande Risposta disabilitata fino a: %1$s - Risposta sbagliata! + Risposta errata! Prossimo N.C. Codice richiesta: %1$s (segna tutte le risposte corrette) diff --git a/app/src/main/res/values-it-rIT/strings.xml b/app/src/main/res/values-it-rIT/strings.xml index fb761cdf60..d687c57827 100644 --- a/app/src/main/res/values-it-rIT/strings.xml +++ b/app/src/main/res/values-it-rIT/strings.xml @@ -1082,7 +1082,6 @@ Cancella completamento Cancella avvio Vuoi resettare l\'avvio dell\'obiettivo? Potresti perdere i tuoi progressi. - Cambio di ora e/o fuso orario sul micro Nessun micro selezionato Seleziona le unità in cui vuoi visualizzare i valori Carica modifiche al profilo locale in NS @@ -1159,7 +1158,6 @@ Autorizzazione fallita Insulina assoluta La password master viene utilizzata per la crittografia del backup e per gestire la sicurezza nell\'applicazione. Ricordala o conservala in un luogo sicuro. - Le password non coincidono Password Master corrente Indicatori di stato Copia impostazioni da NS @@ -1168,123 +1166,6 @@ I tasti vengono sempre visualizzati nella parte inferiore dello schermo Visualizzazione ampia Tema - - Mai connesso - Risveglio - Errore nella comunicazione - Timeout della comunicazione - Micro irraggiungibile - Configurazione non valida - Attivo - In sospensione - - - Integrazione del microinfusore Omnipod, richiede un dispositivo RileyLink (con almeno il firmware 2.0). - - BIP bolo abilitato - BIP basale abilitato - BIP SMB abilitato - BIP TBR abilitato - Opzioni debug pod abilitate - Rilevamento ora legale/fuso orario abilitato - - GSTN pod - Stato pod - %1$.2f U rimanenti - Oltre 50 U - Indirizzo pod - Scadenza pod - No info - Nessun pod connesso - Non inizializzato - Attiva avvisi pod - Conferma avvisi - - Omnipod (433.91 MHz) - - Operazione non possibile.\n\nDevi prima configurare Omnipod. - Operazione non possibile.\n\n Devi attendere qualche minuto che AAPS imposti il profilo per la prima volta. - Illegal PodInitActionType: %1$s - Nessun pod attivo. - Verifica comando fallita. - Si è verificato un errore imprevisto. Segnalalo! (%1$s). - Comunicazione fallita: ricevuti parametri di input non validi. - Comunicazione fallita: timeout. - Comunicazione fallita: si è verificato un errore imprevisto. Segnalalo! - Comunicazione fallita: verifica dell\'integrità del messaggio fallita. - Comunicazione fallita: ricevuto un pacchetto non valido dal pod. - Comunicazione fallita: il pod è in uno stato non corretto. - Comunicazione fallita: ricevuta una risposta non valida dal pod. - Comunicazione fallita: ricevuto dal pod un messaggio con una sequenza numerica non valida. - Comunicazione fallita: ricevuto dal pod un messaggio con un indirizzo non valido. - Comunicazione fallita: non si è riuscito a decodificare il messaggio dal pod. - Comunicazione fallita: risincronizzazione \'nonce\' non riuscita. - Comunicazione fallita: \'nonce\' non sincronizzato. - Comunicazione fallita: non abbastanza dati ricevuti dal pod. - È stato rilevato un guasto al pod (%1$03d %2$s). Disattiva il tuo pod e avviane uno nuovo. - Comunicazione fallita: il pod ha restituito una risposta di errore. - - Gestione pod - Inizializza pod - Disattiva pod - Resetta pod - Storico pod - Imposta bolo - Cancella bolo - Imposta basale temporanea - Cancella basale temporanea (internamente dal driver) - Cancella basale temporanea (forzato da utente) - Imposta piano basale - Ottieni stato pod - Ottieni info pod - Imposta ora - Configurazione avvisi - Conferma avvisi - Sospendi erogazione - Riprendi erogazione - Inserimento sconosciuto - %1$.1f U - %1$.1f U, CH=%2$.1f g - Tasso: %1$.1f U, Durata: %2$d min - Se premi OK, lo stato del pod verrà resettato forzatamente e non potrai più comunicare con il pod. Fallo solo se non riesci più a comunicare con il pod. Se puoi ancora a comunicare con il pod, utilizza l\'opzione Disattiva pod . - Storico pod non disponibile al momento. - Riempi il pod - \nRiempi il nuovo pod con abbastanza insulina per 3 giorni.\n\nResta in ascolto di due bip dal pod durante il processo di riempimento. Questi indicano che è stata inserita la quantità minima di 85U. Assicurati di svuotare completamente la siringa di riempimento, anche dopo aver sentito i due segnali acustici.\n\nDopo il riempimento del pod, premi Avanti.\n\nNota: non rimuovere la protezione dell\'ago del pod in questo momento. - Caricamento - Prova associazione nuovo pod e caricamento.\n\nQuando tutti gli elementi sono stati controllati, puoi premere Avanti.\n\nNota: mantieni il pod molto vicino al RileyLink in questo momento. - Collega il pod - \nPrepara il sito di infusione. Rimuovi la protezione dell\'ago del pod e il supporto adesivo e attacca il pod al sito di infusione.\n\nSe la cannula fuoriesce premi Annulla e cambia il tuo pod.\n\nPremi Avanti per inserire la cannula e iniziare l\'erogazione della basale. - Inserimento cannula - Prova impostazione piano basale iniziale e inserimento cannula.\n\nQuando tutti gli elementi sono stati controllati, puoi premere Avanti. - Info pod - \nIl pod è adesso attivo.\n\nIl tuo piano basale è stato programmato e la cannula è stata inserita.\n\nVerifica che la cannula sia stata inserita correttamente e sostituisci il tuo pod se avverti il contrario. - Disattiva pod - \nPremi Avanti per disattivare il pod.\n\nNota: Questo sospenderà tutta l\'erogazione di insulina e disattiverà il pod. - Disattivazione del pod - Disattivazione del pod.\n\nQuando tutti gli elementi sono stati controllati, puoi premere Avanti.\n\nNota: Se la disattivazione fallisce continuamente, premi Annulla e usa l\'opzione Resetta pod per resettare forzatamente lo stato del pod. - Pod disattivato.\n\nRimuovi il pod dal tuo corpo e gettalo. - Associa pod - Carica pod - Riempi cannula - Imposta profilo basale - Cancella erogazione - Disattiva pod - - - Integrazione del microinfusore Omnipod Dash. - Fine promemoria associazione - Fine promemoria configurazione - Il pod scadrà presto - Il pod scadrà presto - L\'arresto è imminente - Livello serbatoio basso - Avviso sconosciuto - L\'impostazione del profilo basale potrebbe essere fallita. L\'erogazione potrebbe essere sospesa! Ricarica lo stato del pod. - L\'impostazione della basale temporanea potrebbe essere fallita. Se era già in esecuzione una basale temporanea, questa potrebbe essere stata cancellata! Ricarica lo stato del pod. - L\'impostazione dell\'ora potrebbe essere fallita. L\'erogazione potrebbe essere sospesa! Ricarica lo stato del pod. - Impossibile verificare che il bolo sia riuscito. Verifica che il tuo pod stia erogando il bolo oppure cancellalo. - Statistiche RL - Log impulsi Compara profili Assistente profilo Profilo predefinito diff --git a/app/src/main/res/values-iw-rIL/strings.xml b/app/src/main/res/values-iw-rIL/strings.xml index d887a2593b..76002e60dc 100644 --- a/app/src/main/res/values-iw-rIL/strings.xml +++ b/app/src/main/res/values-iw-rIL/strings.xml @@ -12,14 +12,4 @@ מסנכרן את הנתונים שלך עם Nightscout יבא פרופיל מ- Nightscout - - - - - - - - - - diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml index d01047143b..afbaedee45 100644 --- a/app/src/main/res/values-ko-rKR/strings.xml +++ b/app/src/main/res/values-ko-rKR/strings.xml @@ -1005,22 +1005,4 @@ 임시 Basal 요청시간 임시 Basal 실행시간 - - 연결되지 않은 - 시작중 - 연결오류 - 연결시간초과 - 펌프에 연결할 수 없습니다 - 유효하지 않은 설정 - 활성 - 대기 - - - - - - - - - diff --git a/app/src/main/res/values-lt-rLT/strings.xml b/app/src/main/res/values-lt-rLT/strings.xml index 026c0433f1..8470cd44ab 100644 --- a/app/src/main/res/values-lt-rLT/strings.xml +++ b/app/src/main/res/values-lt-rLT/strings.xml @@ -156,6 +156,7 @@ Laikina bazė Ištęstas bolusas Nightscout versija: + Trūksta %1$d g Nustatymai eksportuoti Eksportuoti nustatymus Importuoti nustatymus iš @@ -234,6 +235,10 @@ Minimalus minučių skaičius, kuris turi praeiti nuo vieno boluso, suleisto nuotoliniu būdu iki kito Kiek mažiausiai minučių turi praeiti tarp vieno ir kito boluso Jūsų saugumui, norėdami redaguoti šį pasirinkimą, jums reikia pridėti ne mažiau kaip 2 telefono numerius. + %1$.2f vv bolusas sėkmingai suleistas + Bus suleista %1$.2f vv + %1$.2f vv bolusas sėkmingai suleistas + Bolusas %1$.2f vv sėkmingai suleistas Tikslas %1$s %2$d min. Tikslas %1$s %2$d min. nustatytas sėkmingai Laikinas tikslas atšauktas sėkmingai @@ -257,7 +262,9 @@ Pompa prijungta Nuotolinis valdymas negalimas Nuotolinis bolusas negalimas. Bandykite vėliau. + Norėdami aktyvuoti %1$.2f vv/val bazę, kurios trukmė %2$d min, atsakykite kodu %3$s Norėdami perjungti profilį %1$s %2$d%%, atsakykite kodu %3$s + Norint pradėti ištęstinį bolusą %1$.2f vv %2$d min., atsakykite kodu %3$s Įvedimui %1$dg %2$s atsakykite kodu %3$s Norėdami aktyvuoti %1$d%% bazę %2$d min., atsakykite kodu %3$s Norėdami sustabdyti Ciklą %1$d min., atsakykite kodu %2$s @@ -266,6 +273,7 @@ Ciklo išjungimui atsakykite su kodu %1$s %1$.2f vv/val laikina bazė, kurios trukmė %2$d min., aktyvuota sėkmingai %1$.2f vv ištęstas bolusas, kurio trukmė %2$d min., aktyvuotas sėkmingai + %1$d g angliavandenių įrašyti sėkmingai Įvesti %1$dg angliavandenių nepavyko %1$d%% laikina bazė, kurios trukmė %2$d min., aktyvuota sėkmingai Laikina bazė neaktyvuota @@ -846,6 +854,7 @@ Ar kodas, kurį matote įrenginyje, sutampa su pompos kodu? Insight sujungimas Accu-Chek Insight + %1$.2f vv iš %2$.2f vv suleista %1$s: %2$s Kateteris pakeistas Pompos laikas pakeistas @@ -903,6 +912,7 @@ Ištęstas: %1$.2f / %2$.2f V %3$d min Daugiabangis: %1$.2f / %2$.2f vv %3$d min BPD: %1$.2f + Rez.: %1$.2f vv Bat.: %1$d%% Didž. atkūrimo trukmė [s] Min. atkūrimo trukmė [s] @@ -1045,6 +1055,8 @@ Siųsti SMS: %1$s Siųsti SMS į visus numerius Išsiųsti SMS žinutę su tekstu + AAO prieš AIO + Pritaikytas boluso apribojimas: %1$.2f vv iki %2$.2f vv !!!!! Nustatytas lėtas angliavandenių įsisavinimas: %2$d%% laiko. Dar karą patikrinkite savo skaičiavimus. AAO gali būti pervertinti, todėl gali būti suleista per daug insulino!!!!!]]> Suleisti šią boluso skaičiuoklės rezultato dalį [%] Boluso skaičiuoklė atlieka skaičiavimus, tačiau tik dalis apskaičiuoto insulino yra suleidžiama. Naudinga kartu su SMB algoritmu. @@ -1070,7 +1082,6 @@ Išvalyti užbaigtus Išvalyti pradėtus Ar norite iš naujo nustatyti tikslų pradžią? Jūs galite prarasti jau pasiektus. - Laiko ir/ar laiko zonos pakeitimas pompoje Pompa nepasirinkta Pasirinkite vienetus, kurių vertes norite parodyti Įkelti vietinio profilio pakeitimus į NS @@ -1147,7 +1158,6 @@ Autorizacija nepavyko Insulinas absoliučiais vienetais Pagrindinis slaptažodis naudojamas atsarginiam šifravimui ir programos saugumo ignoravimui. Atsiminkite jį arba laikykite užsirašę saugioje vietoje. - Slaptažodžiai nesutampa Dabartinis pagrindinis slaptažodis Būklės indikatoriai Kopijuoti nustatymus iš NS @@ -1156,123 +1166,6 @@ Mygtukai visada rodomi ekrano apačioje Didelis ekranas Išvaizda - - Niekada nebuvo sujungta - Pažadinimas - Ryšio klaida - Ryšiui skirtas laikas baigėsi - Pompa nepasiekiama - Neteisinga konfigūracija - Aktyvi - Užmigusi - - - Omnipod pompos integracijai reikalingas RileyLink (programinės įrangos versija ne mažiau 2.0). - - Boluso signalas įjungtas - Bazės signalas įjungtas - SMB signalas įjungtas - Laikinos bazės signalas įjungtas - Įgalintos POD derinimo galimybės - Vasaros laiko/laiko juostos aptikimas įgalintas - - POD valdymas - POD būklė - liko %1$.2f U - Daugiau nei 50 U - POD adresas - POD laikas pasibaigs - Nėra informacijos - POD neprijungta - Nepavyko paleisti - Aktyvaus POD signalai - Priimti pranešimus - - Omnipod (433.91 MHz) - - Operacija negalima.\n\n Pirmiausia turite sukonfigūruoti Omnipod pompą prieš atliekant šią operaciją. - Operacija negalima.\n\n Jūs turite palaukti kelias minutes, kol AAPS bando nustatyti profilį pirmą kartą. - Neteisingas inicijavimo tipas:%1$s - Nėra aktyvaus POD. - Komandos patikra nepavyko. - Įvyko netikėta klaida. Prašome pranešti! (tipas: %1$s). - Ryšio klaida: gauti neteisingi įvesties parametrai. - Ryšio klaida: skirtas laikas baigėsi. - Ryšio klaida: įvyko netikėta klaida. Prašome pranešti! - Ryšio klaida: pranešimo vientisumo patikra nepavyko. - Ryšio klaida: netinkami įvesties iš POD parametrai. - Ryšio klaida: Pod būklė yra netinkama. - Ryšio klaida: gautas netinkamas atsakymas iš POD. - Ryšio klaida: iš POD gautas pranešimas su negaliojančiu serijos numeriu. - Ryšio klaida: iš POD gautas pranešimas su netinkamu adresu. - Ryšio klaida: nepavyko iššifruoti pranešimo iš POD. - Ryšio klaida: nepavyko iš naujo sinchronizuoti Nonce. - Ryšio klaida: Nonce nebuvo sinchronizuota. - Ryšio klaida: nepakankamai duomenų gauta iš POD. - Aptikta POD klaida (%1$03d %2$s). Išjunkite POD ir pradėkite naują. - Ryšio klaida: POD pateikė klaidos atsakymą. - - POD valdymas - Inicijuoti POD - Išjungti POD - Atstatyti POD - POD istorija - Nustatyti bolusą - Atšaukti bolusą - Nustatyti laikiną bazę - Atšaukti laikiną bazę (vidinis valdiklis) - Atšaukti laikiną bazę (Inicijuota vartotojo) - Nustatyti bazės tvarkaraštį - Gauti POD būklę - Gauti POD informaciją - Nustatyti laiką - Konfigūruoti perspėjimus - Patvirtinti perspėjimus - Sustabdyti suleidimą - Atnaujinti suleidimą - Nežinomas Įrašas - %1$.1f vv - %1$.1f vv, AV=%2$.1f g - Kiekis: %1$.1f vv, Trukmė: %2$d min - Jei spustelėsite OK, ryšys su POD bus priverstinai nutrauktas ir nebegalėsite prie jo prisijungti. Atlikite tai tik tada, kai AAPS nebegali bendrauti su POD. Jei ryšys su POD vis tiek veikia, naudokite parinktį Išjungti POD. - POD istorija šiuo metu nėra prieinama. - Užpildyti POD - \nUžpildykite naują POD insulinu, kurio pakaktų 3 dienas.\n\nTaip pat atkreipkite dėmesį į du pyptelėjimus iš POD, kai pildote. Tai rodo, kad rezervuaras buvo užpildytas mažiausiai 85vv. Visiškai ištuštinkite švirkštą, net jei girdėjote du pyptelėjimus.\n\nUžpildę POD, spustelėkite Kitas.\n\n Pastaba: vykdant šiuos veiksmus, nenuimkite POD adatos apsauginio dangtelio. - Užpildymas - Pabandykite suporuoti naują POD ir užpildykite jį.\n\nKai pažymėti visi elemetai, galite spustelėti Kitas.\n\n Pastaba: POD ir RileyLink turi būti būti labai arti vienas kito. - Prijunkite POD - \nParuoškite infuzijos vietą. Nuimkite adatos apsauginį dangtelį, pleistro apsaugą ir užklijuokite POD ant infuzijos vietos.\n\nJei kaniulė atšoks, paspauskite Atšaukti ir pakeiskite POD.\n\nSpauskite Kitas, norėdami įvesti kaniulę ir pradėti leisti insuliną. - Įvedama kaniulė - Mėginkite nustatyti pradinį bazės profilį ir įvesti kaniulę.\n\nKai visi elementai yra patikrinti, galite paspausti Kitas. - POD informacija - \nPOD yra aktyvus.\n\nJūsų bazės profilis yra suprogramuotas ir kaniulė įvesta.\n\nPatikrinkite, ar kaniulė buvo tinkamai įvesta, ir, jei jaučiate, kad taip nėra, pakeiskite POD. - Išjungti POD - \nSpustelėkiteKitas, kad išjungtumėte POD.\n\nPastaba: Tai sustabdys insulino leidimą ir išjungs POD. - POD išjungimas - POD išjungimas.\n\nJei visi elementai pažymėti, galite paspausti Kitas.\n\n Pastaba: Jei išjungimas vis nepavyksta, paspauskite Atšaukti ir naudokite parinktį Atstatyti POD , kad priverstinai atkurtumėte POD būklę. - POD išjungtas.\n\nNuimkite POD nuo odos ir jį išmeskite. - POD suporavimas - POD užpildymas - Kaniulės užpildymas - Nustatyti bazės profilį - Atšauti insulino leidimą - Išjungti POD - - - Integracija su Omnipod Dash pompa. - Priminimas apie suporavimo pabaigą - Priminimas apie sąrankos pabaigą - POD galiojimas greitai baigsis - POD galiojimas greitai baigsis - Išjungimas yra neišvengiamas - Žemas rezervuaro lygis - Nežinomas perspėjimas - Gali nepavykti nustatyti bazės profilio. Insulino leidimas gali būti sustabdytas! Atkurkite POD būseną. - Laikinos valandinės bazės nustatymas gali būti nesėkmingas. Jei laikina valandinė bazė iki šiol buvo nustatyta ir galioja, ji gali būti atšaukta! Atnaujinkite POD būseną. - Laiko nustatymas gali būti nesėkmingas. Insulino leidimas gali būti sustabdytas! Atkurkite POD būseną. - Neįmanoma patikrinti, ar bolusas suleistas sėkmingai. Patikrinkite, ar jūsų POD leidžia bolusą, arba bolusą atšaukite. - RL statistika - Pulse žurnalas Palyginti profilius Profilio pagalbininkas Numatytasis profilis diff --git a/app/src/main/res/values-nl-rNL/strings.xml b/app/src/main/res/values-nl-rNL/strings.xml index d0ec392641..4c9dbdacda 100644 --- a/app/src/main/res/values-nl-rNL/strings.xml +++ b/app/src/main/res/values-nl-rNL/strings.xml @@ -1065,7 +1065,6 @@ Voltooiing wissen Wissen gestart Wil je dit leerdoel opnieuw starten? Je kunt je voortgang verliezen. - Tijd en/of tijdzone wijzigen op de pomp Geen pomp geselecteerd Selecteer eenheden waarin je waarden wilt weergeven Upload lokale profielwijzigingen naar NS @@ -1140,7 +1139,6 @@ Authorisatie mislukt Absolute insuline Het masterwachtwoord wordt gebruikt voor het versleutelen van backups en om de app-beveiligingen te kunnen overschrijven. Onthoud het goed of bewaar het op een veilige plaats. - Wachtwoorden komen niet overeen Huidig masterwachtwoord Statusindicatoren Kopieer instellingen van NS @@ -1149,122 +1147,5 @@ Knoppen worden altijd weergegeven aan de onderkant van het scherm Groot scherm Skin - - Nooit verbonden - Ontwaken - Communicatiefout - Time-out op de communicatie - Pomp niet bereikbaar - Ongeldige configuratie - Actief - Slapend - - - Pomp integratie voor Omnipod, vereist RileyLink (met firmware 2.0 of hoger). - - Bolus pieptoon ingeschakeld - Basaal pieptoon ingeschakeld - SMB pieptoon ingeschakeld - Tijdelijk basaal pieptoon ingeschakeld - Pod debugging opties ingeschakeld - DST/tijdzone detectie ingeschakeld - - Pod Beheer - Pod Status - %1$.2f E over - Meer dan 50 E - Pod adres - Pod verloopt - Geen info - Geen pod verbonden - Niet geïnitialiseerd - Actieve pod alarmen - Alarmen bevestigen - - Omnipod (433,91 MHz) - - Bewerking is niet mogelijk.\n\nJe moet eerst Omnipod ingesteld hebben, voordat je deze bewerking kunt gebruiken. - Bewerking is niet mogelijk.\n\nJe moet enkele minuten wachten, totdat AAPS voor de eerste keer probeert om het profiel in te stellen. - Ongeldig PodInitActionType: %1$s - Geen actieve pod. - Opdracht verificatie is mislukt. - Er is een onverwachte fout opgetreden. Rapporteer dit alsjeblieft! (type: %1$s). - Communicatie mislukt: ongeldige invoerparameters ontvangen. - Communicatie mislukt: timeout. - Communicatie mislukt: er is een onvoorziene fout opgetreden. Rapporteer dit alsjeblieft! - Communicatie mislukt: berichtintegriteit kon niet worden geverifieerd. - Communicatie mislukt: ongeldige gegevens ontvangen van de Pod. - Communicatie mislukt: de Pod bevindt zich in een verkeerde staat. - Communicatie mislukt: ongeldig antwoord ontvangen van de Pod. - Communicatie mislukt: bericht met ongeldig volgnummer ontvangen van de Pod. - Communicatie mislukt: bericht met ongeldig adres ontvangen van de Pod. - Communicatie is mislukt: kon bericht van de Pod niet decoderen. - Communicatie mislukt: nonce resync is mislukt. - Communicatie mislukt: nonce out of sync. - Communicatie mislukt: onvoldoende gegevens ontvangen van de Pod. - Een pod-fout (%1$03d %2$s) is gedetecteerd. Deactiveer je Pod en start een nieuwe. - Communicatie mislukt: de Pod heeft een foutrespons gegeven. - - Pod Beheer - Initialiseer Pod - Deactiveer Pod - Reset Pod - Pod Historie - Bolus instellen - Annuleer Bolus - Instellen Tijdelijke Basaal - Annuleer Tijdelijk Basaal (Intern door stuurprogramma) - Annuleer Tijdelijk Basaal (Geforceerd door gebruiker) - Basaalprofiel instellen - Pod status ophalen - Pod info ophalen - Tijd instellen - Configureer alarmen - Bevestig alarmen - Onderbreek toediening - Hervat toediening - Onbekende invoer - %1$.1f E - %1$.1f E, KH=%2$.1f g - Basaal: %1$.1f E, Duur: %2$d min - Als je op OK klikt, zal de Pod gedwongen worden gereset en kun je niet meer communiceren met de Pod. Doe dit alleen als je al niet meer met de Pod kunt communiceren. Als je nog wel kunt communiceren met de Pod, gebruik dan de optie Deactiveer Pod. - Pod Historie momenteel niet beschikbaar. - Vul de Pod - \nVul de nieuwe Pod met voldoende insuline voor 3 dagen.\n\nLuister of je twee piepjes hoort tijdens het vullen. Deze geven aan dat de minimum hoeveelheid van 85E is bereikt. Ook als je de twee piepjes hebt gehoord ga je verder met vullen totdat de vulspuit volledig leeg is.\n\nNa het vullen van de Pod druk je op Volgende.\n\nOpmerking: verwijder de beschermkap van de Pod naald nog niet! - Uitvullen - Probeer te koppelen met de nieuwe Pod en laat de Pod de naald uitvullen.\n\nWanneer alle onderdelen zijn afgerond, druk je op Volgende.\n\nOpmerking: Houd de Pod goed dicht bij de RileyLink terwijl je dit doet. - Plaats de Pod - \nBereid het plaatsen voor. Verwijder de beschermdop van de naald en haal de papiertjes van de sticker.\n\n(Mocht je zien dat de canule uitsteekt, druk dan op Annuleren en begin overnieuw met een andere Pod.)\n\nBevestig de Pod op de huid. Druk op Volgende om de canule te gaan inschieten en de insulinetoediening te laten starten. - Canule inschieten - De basaalstand wordt ingesteld en de canule wordt ingeschoten.\n\nWanneer alle onderdelen zijn afgerond, druk je op Volgende. - Pod Info - \nDe Pod is nu actief.\n\nJouw basaalprofiel is ingeladen in de Pod en de canule is ingebracht.\n\nControleer of de canule correct is geplaatst en vervang de Pod als je denkt dat er iets is misgegaan. - Deactiveer Pod - \nDruk op Volgende om de Pod te deactiveren.\n\nOpmerking: Hiermee wordt de insuline toediening gestopt en wordt de Pod gedeactiveerd. - Deactiveren van de Pod - Deactiveren van de Pod.\n\nWanneer alle onderdelen zijn afgerond, druk je op Volgende.\n\nOpmerking: Als deactiveren herhaaldelijk niet wil lukken, druk je op Annuleren en gebruik de optie Reset Pod om de Pod-status geforceerd te deactiveren. - Pod gedeactiveerd.\n\nVerwijder de Pod van je lichaam en gooi hem weg. - Pod Koppelen - Pod Uitvullen - Canule vullen - Instellen Basaal Profiel - Annuleer toediening - Deactiveer Pod - - - Pomp integratie voor Omnipod Dash. - Herinnering koppeling afronden - Herinnering setup afronden - Pod verloopt binnenkort - Pod verloopt binnenkort - Schakelt zeer binnenkort uit - Laag reservoir - Onbekend alarm - Het instellen van basaal profiel is mogelijk mislukt. De toediening is misschien gestopt! Vernieuw de status van Pod. - Het instellen van tijdelijk basaal is mogelijk mislukt. Als er al een tijdelijk basaal actief was, is dat misschien geannuleerd! Vernieuw de status van de Pod. - Het instellen van de tijd is mogelijk mislukt. De toediening is misschien gestopt! Vernieuw de status van Pod. - Kan niet controleren of de bolus is geslaagd. Controleer of de Pod de bolus aan het toedienen is of annuleer de bolus. - RL Statistieken - Pulsen Log Profiel hulp diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index e97fba0680..fedb054b31 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -1066,7 +1066,6 @@ Wyczyść skończone Wyczyść rozpoczęte Czy chcesz zresetować czas rozpoczęcia zadania? Możesz utracić postępy. - Zmiana czasu i/lub strefy czasowej w pompie Nie wybrano pompy Wybierz jednostki, w których chcesz wyświetlać wartości Prześlij zmiany w profilu lokalnym do NS @@ -1142,7 +1141,6 @@ Autoryzacja nie powiodła się Cała insulina Hasło główne jest używane do szyfrowania kopii zapasowych i przełamania zabezpieczeń w aplikacji. Zapamiętaj je lub przechowuj w bezpiecznym miejscu. - Hasła się nie zgadzają! Aktualne hasło główne Wskaźniki stanu Kopiowanie ustawień z NS @@ -1151,123 +1149,6 @@ Przyciski są zawsze wyświetlane na dole ekranu Duży ekran Motyw - - Nigdy nie połączona - Wybudzanie - Błąd komunikacji - Przekroczony limit czasu połączenia - Pompa nieosiągalna - Nieprawidłowe ustawienia - Aktywna - Uśpiona - - - Integracja pompy Omnipod, wymaga RileyLink (z firmwarem 2.0 lub wyższym). - - Sygnał dźwiękowy bolusa włączony - Sygnał dźwiękowy bazy włączony - Sygnał dźwiękowy SMB włączony - Sygnał dźwiękowy TBR (tymczasowej dawk bazowej) włączony - Włączone opcje debugowania PODów - Włączone wykrywanie stref czasowych - - Pod Mgmt - Status Pod - %1$.2f U zostało - Ponad 50 U - Adres Pod - Pod traci ważność - Brak informacji - Pod nie podłączony - Nie zainicjowany - Aktywne alarmy Pod - Alerty ack - - Omnipod (433,91 MHz) - - To działanie nie jest możliwe.\n\n Musisz skonfigurować Omnipod przed uruchomieniem tego działania. - Operacja nie jest możliwa.\n\n Trzeba poczekać kilka minut, aż AAPS spróbuje ustawić profil pierwszy raz. - Niedozwolone działanie PodInitActionType: %1$s - Brak aktywnego Pod. - Nieudana weryfikacja polecenia. - Wystąpił nieoczekiwany błąd. Proszę zgłosić! (typ: %1$s). - Komunikacja nie powiodła się: odebrano niepoprawne parametry wejściowe. - Komunikacja nie powiodła się: przekroczono limit czasu. - Komunikacja nie powiodła się: wystąpił nieoczekiwany błąd. Proszę zgłosić! - Komunikacja nie powiodła się: weryfikacja integralności komunikatu nie powiodła się. - Komunikacja nie powiodła się: odebrano niepoprawny pakiet (komunikat) z Poda. - Komunikacja nie powiodła się: Pod jest w niewłaściwym stanie. - Komunikacja nie powiodła się: odebrano niepoprawną odpowiedź (pakiet) z Poda. - Komunikacja nie powiodła się: odebrano komunikat z niepoprawną sekwencją liczb z Poda. - Komunikacja nie powiodła się: odebrano komunikat z niepoprawną adresacją z Poda. - Komunikacja nie powiodła się: nie powiodło się dekodowanie komunikatu z Poda. - Komunikacja nie powiodła się: nonce resync nie powiodło się. - Komunikacja nie powiodła się: nonce nie jest zsynchronizowane. - Komunikacja nie powiodła się: brak wystarczającej ilości danych odebranych z Poda. - Błąd Pod. (%1$03d %2$s) został wykryty. Zdezaktywuj swój Pod i uruchom nowy. - Komunikacja nie powiodła się: Pod zwrócił odpowiedź o błędzie. - - Zarządzanie Pod - Uruchom Pod - Odłącz Pod - Resetuj Pod - Historia Pod - Podanie bolusa - Anulowanie bolusa - Ustaw tymczasową dawkę bazową - Anuluj tymczasową bazę (wewnętrznie przez sterownik) - Anuluj tymczasową bazę (wymuszone przez użytkownika) - Ustaw harmonogram Dawki bazowej - Pobierz status Pod - Pobierz informacje o Pod - Ustaw czas - Konfigurowanie alertów - Potwierdź alerty - Wstrzymaj podawanie - Wznów podawanie - Nieznany Wpis - %1$.1f U - %1$.1f U, CH=%2$.1f g - Dawka: %1$.1f U, Czas: %2$d min - Jeśli naciśniesz OK, stan Pod zostanie wyzerowany i nie będziesz mógł więcej komunikować się z tym Podem. Zrób to tylko wtedy, gdy nie możesz się z nim skmunikować. Jeśli nadal można komunikować się z Podem, skorzystaj z opcji Odłącz Pod. - Historia Pod nie jest dostępna w tej chwili. - Napełnij Pod - \nNapełnij nowego Poda z wystarczającą ilością insuliny przez 3 dni.\n\nNasłuchuj dwóch sygnałów dźwiękowych z Poda podczas procesu napełniania. Wskazują one, że minimalna ilość 85U została wypełniona. Należy upewnić się, że ampułkostrzykawka jest całkowicie pusta, nawet po odsłuchaniu dwóch sygnałów dźwiękowych.\n\nPo napełnieniu Poda, należy nacisnąć Dalej.\n\nUwaga: nie usuwaj w tym czasie osłonki igłowej Poda. - Wypełnianie - Próba sparowania z nowym Podem i wypełnienia go.\n\nKiedy wszystkie elementy są sprawdzone, można nacisnąć Następny.\n\nUwaga: prosimy o trzymanie w tym czasie Poda bardzo blisko RileyLink. - Przymocuj Poda - \nPrzygotowanie miejsca do infuzji. Zdjąć osłonkę igły i zabezpieczenie plastra i przykleić Pod do skóry w miejscu wkłucia.\n\nJeśli kaniula odkleja się, proszę wcisnąć Anuluj i odczepić Pod.\n\nNaciśnij Następny w celu wprowadzenia kaniuli i rozpoczęcia podawania bazy. - Wprowadzanie kaniuli - Próba ustawienia początkowego planu bazowego i wprowadzeia kaniuli.\n\nKiedy wszystkie elementy są sprawdzane, można nacisnąć Następny. - Informacje o Podzie - \nPod jest teraz aktywny.\n\nTwój plan dawki bazowej został zaprogramowany i wprowadzono kaniulę w miejsce wkłucia.\n\nSprawdź, czy kaniula została prawidłowo włożona i wymień swój Pod, jeśli czujesz, że nie. - Odłącz Pod - \nNaciśnij Następny w celu odłączenia Poda.\n\nUwaga: To spowoduje zawieszenie wszystkich dostaw insuliny i dezaktywację Poda. - Odłączanie Poda - Deaktywacja Pod.\n\nKiedy wszystkie elementy są zaznaczone, możesz nacisnąć Następna.\n\nUwaga: Jeśli deaktywacja w sposób ciągły nie powodzi się, należy nacisnąć Anuluj i użyć opcji Reset Pod, aby wymusić zresetowanie stanu Pod. - Pod odłączony.\n\nProszę odkleić Pod od ciała i wyrzucić go. - Sparuj Pod - Wypełnij Pod - Wypełnij kaniulę - Ustaw profil dawki bazowej - Anulowanie podawania - Odłącz Pod - - - Integracja pompy dla Omnipod Dash. - Zakończ przypomnienie parowania - Zakończ przypomnienie o konfiguracji - Pod wkrótce straci ważność - Pod wkrótce straci ważność - Wyłączenie jest nieuchronne - Niski poziom w zbiorniku - Nieznany alarm - Ustawienie profilu podstawowego mogło się nie powieść. Podawanie mogło zostać zawieszone! Odśwież status Pod. - Ustawienie bazy tymczasowej mogło się nie powieść. Jeśli była już uruchomiona baza tymczasowa, to mogła zostać odwołana! Odśwież status Pod. - Ustawienie czasu mogło się nie powieść. Podawanie mogło zostać zawieszone! Odśwież status Pod. - Nie można sprawdzić, czy podano bolus. Upewnij się, że Twój Pod podaje bolus lub odwołaj go. - Statystyki RL - Logi pulsów omnipod Porównaj profile Pomocnik profilu Profil domyślny diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 9ccd7c2cf4..27560b4cd6 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -1093,35 +1093,10 @@ Falha na autorização Insulina absoluta Password Mestre é usada para encriptação da cópia de segurança e substituir segurança na aplicação. Lembre-se dela ou guarde-a em um lugar seguro. - As passwords não coincidem Senha mestra atual Copiar definições do NS Tema original Botões são sempre exibidos na parte inferior da tela Mostrador Grande Tema - - Nunca contatado - A acordar - Erro com comunicação - Tempo limite para comunicação - Bomba inacessível - Configuração inválida - Ativo - A dormir - - - - - - - - Desativado Pod - Definir Bólus - Definir Basal temporário - %1$.1f U - Definir Perfil Basal - Desativado Pod - - diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 28691e1395..99ddc71a2d 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -156,6 +156,7 @@ BasalTemp Bólus Prolongado Versão Nightscout: + A faltar %1$d g Preferências exportadas Exportar configurações para Importar configurações de @@ -234,6 +235,10 @@ Número mínimo de minutos que deve decorrer entre um bólus remoto e o próximo Quantos minutos deve decorrer, pelo menos, entre um bólus e o próximo Para sua segurança, para editar esta preferência você precisa adicionar pelo menos 2 números de telefone. + Bólus %1$.2f U administrador com sucesso + A ser administrado %1$.2f U + Bólus %1$.2f U administrador com sucesso + Bólus de Refeição %1$.2f U administrado com sucesso Alvo %1$s para %2$d minutos Alvo %1$s para %2$d minutos definido com sucesso Alvo Temp cancelado com êxito @@ -257,7 +262,9 @@ Bomba ligada novamente O comando remoto não é permitido O bólus remoto não está disponível. Tente novamente mais tarde. + Para iniciar basal %1$.2f U/h por %2$d min responda com o código %3$s Para mudar o perfil para %1$s %2$d%% responda com o código %3$s + Para iniciar bólus prolongado %1$.2f U por %2$d min responda com o código %3$s Para inserir %1$dg em %2$s responda com código %3$s Para começar a basal %1$d%% U/h durante %2$d min responda com o código %3$s Para suspender o loop por %1$d minutos resposta com código %2$s @@ -266,6 +273,7 @@ Para desactivar o loop responda com o código %1$s Basal temporária %1$.2fU/h para %2$d min iniciada com êxito Bólus prolongado %1$.2fU/h para %2$d min iniciado com êxito + Hidratos %1$d g inseridos com sucesso Introdução de %1$dg de hidratos falhou Basal temporária %1$d%% U/h durante%2$d min iniciada com êxito Início basal temp falhou @@ -551,6 +559,7 @@ Bomba inacessível Leituras Glic. perdidas Usar as notificações do sistema para alertas e notificações + Aumentar gradualmente o volume de alertas e notificações Alertas local Alerta caso nenhuma glicemia seja recebida Alerta caso não seja possivel alcançar a bomba @@ -846,6 +855,7 @@ Os códigos exibidos neste dispositivo e na sua bomba correspondem? Emparelhamento Insight Accu-Chek Insight + %1$.2f U / %2$.2f U administrado %1$s: %2$s Tubo mudado Hora da bomba actualizada @@ -903,6 +913,7 @@ Prolongado: %1$.2f / %2$.2f U por %3$d min Multionda: %1$.2f / %2$.2f U por %3$d min TDD: %1$.2f + Reser.: %1$.2f U Bat.: %1$d%% Duração máxima da recuperação [s] Duração mínima da recuperação [s] @@ -1045,6 +1056,8 @@ Enviar SMS: %1$s Enviar SMS para todos os números Enviar SMS com texto + COB vs IOB + Restrição de bólus aplicada: %1$.2f U a %2$.2f U !!!!! Absorção lenta de hidratos detectada: %2$d%% do tempo. Verifique o seu cálculo. COB pode estar sobreestimado, assim mais insulina pode ser dada !!!]]> Administrar esta parte do resultado do assistente de bólus [%] Assistente de bólus executa o cálculo, mas apenas esta parte da insulina calculada é administada. Útil com o algoritmo SMB. @@ -1070,7 +1083,6 @@ Limpar terminado Limpar iniciado Deseja reiniciar o objectivo? Pode perder seu progresso. - Alterar Hora e/ou Fuso Horário na Bomba Nenhuma bomba seleccionada Seleccione as unidades em que deseja exibir os valores Carregar as alterações do perfil local para NS @@ -1147,7 +1159,6 @@ Falha na autorização Insulina absoluta Senha Mestre é usada para encriptação da cópia de segurança e substituir segurança na aplicação. Lembre-se dela ou guarde-a em um lugar seguro. - As senhas não coincidem Senha Mestre actual Luzes de Estado Copiar definições do NS @@ -1156,123 +1167,6 @@ Os botões são sempre exibidos na parte inferior do ecrã Mostrador Grande Tema gráfico - - Nunca contactado - A acordar - Erro com comunicação - Tempo limite para comunicação - Bomba inacessível - Configuração inválida - Activo - A dormir - - - Integração de bomba para Omnipod, requer RileyLink (com pelo menos firmware 2.0) dispositivo. - - Sinal Bólus Activado - Sinal Basal Activado - Sinal SMB Activado - Sinal DBT Activado - Opções de Depuração do Pod habilitadas - Detecção de DST/Fuso Horário Activado - - Gestão Pod - Estado do Pod - %1$.2f U restante - Mais de 50 U - Endereço do Pod - Pod Expira - Sem info - Nenhum Pod ligado - Não inicializado - Alertas Pod Activos - Reco Alertas - - Omnipod (433.91 MHz) - - A operação não é possível.\n\nPrecisa configurar o Omnipod primeiro, antes de pode usar esta operação. - A operação não é possível.\n\n Precisa de esperar alguns minutos, até que AAPS tente definir o perfil para a primeira vez. - PodInitActionType Ilegal: %1$s - Nenhum Pod Activo. - A verificação do comando falhou. - Ocorreu um erro inesperado. Por favor reporte! (digite: %1$s). - Falha na comunicação: foram recebidos parâmetros de entrada inválidos. - Falha na comunicação: tempo limite. - Falha na comunicação: ocorreu um erro inesperado. Por favor, reporte! - Falha na comunicação: mensagem de falha de verificação de integridade. - Falha na comunicação: recebeu um pacote inválido do Pod. - Falha na comunicação: o Pod está em um estado errado. - Falha na comunicação: recebeu uma resposta inválida do Pod. - Falha na comunicação: recebeu uma mensagem com número de sequência inválido do Pod. - Falha na comunicação: recebeu uma mensagem com um endereço inválido do Pod. - Falha na comunicação: falha ao descodificar a mensagem do Pod. - Falha na comunicação: nonce resync falhou. - Falha na comunicação: nonce fora de sincronização. - Falha na comunicação: não há dados suficientes recebidos do Pod. - Uma falha de Pod (%1$03d %2$s) foi detectada. Por favor, desactive o Pod e inicie um novo. - Falha na comunicação: o Pod devolveu uma resposta de erro. - - Gestão Pod - Iniciar Pod - Desactivar Pod - Repor Pod - Histórico do Pod - Definir Bólus - Cancelar Bólus - Definir Basal Temporária - Cancelar Basal Temporária (Forçado pelo controlador) - Cancelar Basal Temporária (Forçado pelo utilizador) - Definir Programação Basal - Obter Status do Pod - Obter Pod Info - Definir Hora - Configurar Alertas - Reconhecer Alertas - Suspender Administração - Retomar Administração - Entrada Desconhecida - %1$.1f U - %1$.1f U, HC=%2$.1f g - Taxa: %1$.1f U, Duração: %2$d min - Se pressionar OK, o estado do Pod vai ser forçado a redefinir e você não será capaz de comunicar mais com o Pod. Faça isso somente se você não pode comunicar mais com o Pod. Se ainda pode comunicar com o Pod, por favor, use o Desactivar Pod opção. - Histórico do Pod não disponível no momento. - Encher o Pod - \nPreencher o novo Pod com insulina suficiente para 3 dias.\n\nOuvir dois sinais sonoros a partir do Pod durante o processo de enchimento. Isso indica que a quantidade mínima de 85U foi inserida. Certifique-se de esvaziar completamente a seringa, mesmo depois de ouvir dois sinais sonoros.\n\nDepois de preencher o Pod, por favor, pressione Próximo.\n\nNota: não remova a tampa da agulha do Pod neste momento. - A Purgar - A tentar emparelhar com o novo Pod e purgá-lo.\n\nQuando todos os itens forem verificados, pode pressionar Próximo.\n\nNota: por favor, mantenha o Pod muito perto do RileyLink neste momento. - Anexar o Pod - \nPrepare o local de infusão. Remova a tampa da agulha do Pod e o adesivo e fixe o Pod no local de infusão.\n\nSe a canula sair, por favor, pressione Cancelar e descarte o seu Pod.\n\nPressione Próximo para inserir a canula e começar a administração da basal. - A inserir canula - A tentar definir um plano da basal inicial e inserir canula.\n\nQuando todos os itens estiverem verificados, pode pressionar Próximo. - Info Pod - \nO Pod está agora activo.\n\nO seu plano de basal foi programado e a canula foi inserida.\n\nPor favor, verifique se a canula foi inserida correctamente e substitua o seu Pod se você se sente que não. - Desactivar Pod - \nPressione Próximo para desactivar o Pod.\n\nNota: Isto irá suspender toda a administração de insulina e desactivar o Pod. - A Desactivar Pod - A desactivar o Pod.\n\nQuando todos os itens forem verificados, pode pressionar Próximo.\n\nNota: Se desactivar falhar continuamente, por favor, pressione Cancelar e use o Repor Pod opção para forçar a repor o estado do Pod. - Pod desactivado.\n\nPor favor, remova o Pod do seu corpo e descarte-o. - Emparelhar Pod - Purgar Pod - Enchimento de Canula - Definir Perfil Basal - Cancelar Administração - Desactivar Pod - - - Integração da Bomba para Omnipod Dash. - Lembrete Concluir Emparelhamento - Lembrete Terminar Configuração - Pod vai expirar em breve - Pod vai expirar em breve - Encerramento iminente - Reservatório baixo - Alerta desconhecido - Pode ter falhado ao definir perfil da basal. A administração pode estar suspensa! Por favor, actualize o estado do Pod. - Pode ter falhado ao definir basal temporária. Se houve uma basal temporária já em execução, pode ter sido cancelada! Por favor, actualize o estado do Pod. - Pode ter falhado ao definir a hora. A administração pode estar suspensa! Por favor, actualize o estado do Pod. - Não é possível verificar se o bólus foi bem-sucedido. Por favor, verifique se o Pod está administrar ou cancelar o bólus. - Estatísticas RL - Registo de Pulse Comparar Perfis Assistente de Perfil Perfil Padrão diff --git a/app/src/main/res/values-ro-rRO/strings.xml b/app/src/main/res/values-ro-rRO/strings.xml index f04d78c2d8..573bdb13fe 100644 --- a/app/src/main/res/values-ro-rRO/strings.xml +++ b/app/src/main/res/values-ro-rRO/strings.xml @@ -1070,7 +1070,6 @@ Șterge starea \"Terminat\" Șterge starea \"Început\" Doriți să reîncepeți obiectivul? Vă puteți pierde progresul. - Schimbare oră și/sau fus orar în pompă Nicio pompă selectată Selectați unitățile în care doriți să afișați valorile Transmiteți modificările profilului local către NS @@ -1147,7 +1146,6 @@ Autorizarea a eșuat Insulină totală Parola master (principală) este folosită pentru criptarea copiilor de rezervă și pentru a suprascrie securitatea în aplicație. Rețineți-o sau păstrați-o într-un loc sigur. - Parolele nu coincid Parola principală curentă Lumini de stare Copiați setările din NS @@ -1156,123 +1154,6 @@ Butoanele sunt afișate întotdeauna în partea de jos a ecranului Display mare Tema - - Niciodată contactată - Se pornește - Eroare de comunicație - Comunicația nu a reușit la timp - Pompă indisponibilă - Configurație invalidă - Activă - În repaus - - - Integrare pompa pentru Omnipod, necesită dispozitivul RileyLink (cu versiune firmware de cel puțin 2.0). - - Bip pentru Bolus Activat - Bip pentru Bazală Activat - Bip pentru SMB Activat - Bip pentru TBR Activat - Opțiuni de depanare Pod Activate - Detectare DST/fus orar activată - - Pod Mgmt - Status Pod - %1$.2f U rămase - Peste 50 U - Adresă Pod - Pod-ul expiră - Nu există informații - Niciun Pod conectat - Neiniţializat - Alerte pod active - Alerte de confirmare - - Omnipod (433.91 MHz) - - Operațiunea nu este posibilă.\n\nTrebuie să configuraţi Omnipod înainte de a putea efectua această operațiune. - Operaţiunea nu este posibilă.\n\n Trebuie să aşteptaţi câteva minute până când AAPS încearcă să seteze profilul pentru prima dată. - Acțiune PodInitActionType ilegala: %1$s - Niciun Pod activ. - Verificarea comenzii a eşuat. - A apărut o eroare neașteptată. Vă rugăm să o raportați! (tip: %1$s). - Comunicarea a eșuat: s-au primit parametri de intrare incorecți. - Comunicarea a eșuat: timpul a expirat. - Comunicarea a eşuat: a apărut o eroare neaşteptată. Vă rugăm să o raportaţi! - Comunicarea a eşuat: verificarea integrităţii mesajului a eşuat. - Comunicarea a eşuat: a fost primit un pachet invalid de la Pod. - Comunicarea a eșuat: Pod-ul este într-o stare incorectă. - Comunicarea a eșuat: s-a primit un răspuns incorect de la Pod. - Comunicarea a eșuat: s-a primit un mesaj cu un număr de secvență invalid de la Pod. - Comunicarea a eșuat: s-a primit un mesaj cu o adresă invalidă de la Pod. - Comunicarea a eșuat: nu s-a reușit decodarea mesajului de la Pod. - Comunicarea a eșuat: resincronizarea nonce nu a reușit. - Comunicarea a eșuat: nonce nu poate fi sincronizată. - Comunicarea a eşuat: nu s-au primit suficiente date de la Pod. - A fost detectată o eroare a Pod-ului (%1$03d %2$s). Vă rugăm să îl dezactivați pe acesta și să porniți unul nou. - Comunicarea a eșuat: Pod-ul a returnat un răspuns de eroare. - - Gestionare Pod - Inițializare Pod - Dezactivare Pod - Resetare Pod - Istoric Pod - Setează bolusul - Anulați Bolus - Setează bazala temporară - Anulați bazală temporară (la nivel intern de către driver) - Anulați bazală temporară (impus de către utilizator) - Programați ratele bazale - Obțineți Status Pod - Obțineți Informații Pod - Setare timp - Configurare alerte - Confirmare alerte - Suspendați Livrarea - Reluați livrarea - Intrare necunoscută - %1$.1f U - %1$.1f U, CH=%2$.1f g - Rata: %1$.1f U, Durata: %2$d min - Dacă apăsați OK, statusul Pod-ului va fi resetat forțat şi nu veți mai putea comunica cu Pod-ul. Faceți acest lucru numai dacă nu mai puteți comunica deloc cu Pod-ul. Daca mai puteți comunica cu Pod-ul, va rugam sa folosiți opțiunea Dezactivare Pod. - Istoricul Pod-ului nu este disponibil momentan. - Umpleţi Pod-ul - \nUmpleți noul Pod cu suficientă insulină pentru 3 zile.\n\nAr trebui sa auziți două bipuri de la Pod în timpul procesului de umplere. Acestea indică faptul că, cantitatea minimă de 85U a fost introdusă. Asigurați-vă ca ați golit complet seringa de umplere, chiar și după ce ați auzit două bipuri.\n\nDupă umplerea Pod-ului, vă rugăm să apăsați Următorul.\n\nNotă: Nu scoateți capacul transparent al acului in acest moment. - Amorsare - Încercare de împerechere cu noul Pod și amorsare.\n\nAtunci când toate etapele sunt gata, puteți apăsa Următorul.\n\nNotă: vă rugăm să țineți Pod-ul foarte aproape de RileyLink în timpul procesului. - Atașați Pod-ul - \nPregătiți setul de infuzie. Scoateți capacul acului și suport adeziv și atașați Pod-ul la locul de infuzie.\n\nDacă, canula pare in neregulă, apăsați Anulare și aruncați Pod-ul.\n\nApăsați Următorul pentru a introduce canula și a începe livrarea bazalei. - Inserare canulă - Încercare de programare inițială a ratelor bazale si de insertie a canulei.\n\nCând toate elementele sunt gata, puteți apăsa Următorul. - Informații Pod - \nPod-ul este acum activ.\n\nRatele bazale au fost programate și canula a fost introdusă.\n\nVă rugăm să verificați că acul a fost introdus corect. Dacă considerați ca nu, înlocuiți Pod-ul. - Dezactivare Pod - \nApăsați Următorul pentru a dezactiva Pod-ul.\n\nNotă: Acest lucru va suspenda orice livrare de insulină și va dezactiva Pod-ul. - Dezactivare Pod - Dezactivare Pod.\n\nAtunci când toate elementele sunt gata, puteți apăsa Următorul.\n\nNotă: Dacă dezactivarea eșuează continuu, vă rugăm să apăsați Anulează și folosiți opțiunea Resetare Pod pentru a forța resetarea Pod-ului. - Pod dezactivat.\n\nScoateți Pod-ul și aruncați-l. - Împerechere Pod - Amorsare Pod - Umplere Canulă - Setează profilul bazalelor - Anulare livrare - Dezactivare Pod - - - Integrare cu pompa pentru Omnipod Dash. - Finalizare memento împerechere - Finalizare memento setare - Pod-ul va expira în curând - Pod-ul va expira în curând - Oprirea este iminentă - Nivel rezervor scăzut - Alertă necunoscută - Setarea ratelor bazale s-ar putea să fi eșuat. Livrarea ar putea fi suspendată! Vă rugăm să reactualizați starea Pod-ului. - Setarea ratelor bazale temporare s-ar putea să fi eșuat. Dacă a existat o bazală temporară în livrare, aceasta ar putea fi fost anulată! Vă rugăm să reactualizați starea Pod-ului. - Setarea datei și orei s-ar putea să fi eșuat. Livrarea ar putea fi suspendată! Vă rugăm să reactualizați starea Pod-ului. - Nu se poate verifica dacă bolusul a reușit. Verificați dacă Pod livrează ceva sau anulați bolusul. - Statistici RL - Jurnal Puls Compară profilurile Ajutor profil Profil implicit diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml index f44a07ebd3..6adf98bb48 100644 --- a/app/src/main/res/values-ru-rRU/strings.xml +++ b/app/src/main/res/values-ru-rRU/strings.xml @@ -1084,7 +1084,6 @@ Context | Edit Context Очистить завершенные Очистить начатые Хотите сбросить начатую цель? Можете потерять уже достигнутое. - Изменение времени и/или часового пояса на помпе Помпа не выбрана Выберите единицы, в которых вы хотите отображать значения Перенести изменения локального профиля в NS @@ -1161,7 +1160,6 @@ Context | Edit Context Ошибка авторизации Абсолютный инсулин Главный пароль используется для шифрования резервных копий и для переопределения защиты в приложении. Запомните его или храните в безопасном месте. - Пароли не совпадают Текущий главный пароль Индикаторы состояния Копировать параметры из NS @@ -1170,123 +1168,6 @@ Context | Edit Context Кнопки всегда отображаются в нижней части экрана Большой дисплей Тема оформления - - Никогда не подключалось - Пробуждение - Ошибка связи - Таймаут связи - Помпа недоступна - Недопустимая конфигурация - Активно - Сон - - - Для интеграции с помпой Omnipod требуется устройство RileyLink (с прошивкой 2.0 и выше). - - Звуковой сигнал болюса включен - Звуковой сигнал базала включен - Звуковой сигнал микроболюса SMB включен - Звуковой сигнал временного базала TBR включен - Опции Отладки Пода Включены - Включено обнаружение часового пояса - - Управление помпой - Статус помпы - %1$.2f ед. осталось - Более 50 ед. - Адрес Пода - Срок действия Пода истекает - Нет информации. - Нет подключения к помпе - Нет инициализации - Активные оповещения помпы - Оповещения помпы - - Omnipod (433.91 МГц) - - Операция невозможна.\n\n Сначала нужно настроить помпу Omnipod. - Операция невозможна.\n\n Подождите несколько минут, пока AAPS пытается задать профиль. - Недопустимый тип инициализации: %1$s - Активная помпа не выбрана. - Командная верификация не состоялась. - Произошла непредвиденная ошибка. Пожалуйста, сообщите об ошибке! (сообщить:: %1$s). - Ошибка связи: недопустимые входные параметры. - Ошибка связи: время ожидания истекло. - Ошибка связи: возникла непредвиденная ошибка. Пожалуйста, сообщите! - Ошибка связи: проверка целостности сообщения завершилась неудачно. - Ошибка связи: недопустимые входные параметры. - Ошибка связи: Pod находится в неверном состоянии. - Ошибка связи: недопустимый ответ от помпы. - Ошибка связи: получено сообщение с недопустимым порядковым номером от Pod. - Ошибка связи: получено сообщение с некорректным адресом от Pod. - Ошибка связи: не удалось декодировать сообщение от Pod. - Ошибка соединения: не удалось выполнить синхронизацию nonce resync. - Ошибка соединения: вне синхронизации. - Ошибка связи: недостаточно данных от Pod. - Обнаружена ошибка Pod (%1$03d %2$s). Деактивируйте Pod и запустите новый. - Ошибка связи: Pod ответил ошибкой. - - Управление помпой Omnipod - Инициализировать Pod - Деактивировать Pod - Сброс помпы - Журнал помпы - Настроить болюс - Отменить болюс - Установить временный базал - Отменить временный базал (внутренний драйвер) - Отменить временный базал (принудительно пользователем) - Задать расписание базала - Получить состояние Pod - Получить информацию о Pod - Установить Время - Сконфигурировать оповещения - Подтвердить оповещения - Приостановить подачу - Возобновить подачу - Неизвестная запись - %1$.1f ед - %1$.1f ед, CH=%2$.1f г - Скорость: %1$.1f ед, Продолжительность: %2$d мин - Если нажать OK, состояние Pod будет принудительно сброшено, и вы больше не сможете общаться с Pod. Сделайте это только в том случае, если вы не можете обмениваться с Pod. Если еще можно связаться с Pod, воспользуйтесь опцией Деактивировать Pod. - В настоящее время история помпы недоступна. - Заполнить Pod - \nЗаполните новый Pod запасом инсулина на 3 дня.\n\nПоступят два звуковых сигнала от помпы во время заправки. Это означает, что минимальное количество 85U заправлено. Не забудьте опустошить заправочный шприц даже после того, как услышите два звуковых сигнала.\n\nПосле заполнения Pod нажмите Next.\n\nПримечание: Пока не снимайте с помпы колпачок с иглой. - Первичное заполнение инфузионной секции пода - Попытка сопряжения с новым Podом и первичного заполнения инфузионного отсека..\n\n После проверки всех пунктов можно нажать Далее.\n\nПримечание: В это время Под должен находиться рядом с RileyLink. - Подключить Под - \nПодготовьте место инфузии. Удалите колпачок с иглы и защиту липкого слоя, Установите Pod на тело.\n\nесли канюля выступает, нажмите отменить и утилизируйте Pod.\n\Нажмите Далее чтобы вставить канюлю и начать подачу базала. - Установка канюли (катетера) - Определение графика подачи базала и установка канюли. \n\n Когда проверены все шаги, нажмите Далее. - Информация о Pod - \nПомпа сейчас активна.\n\nБазальный график запрограммирован и катетер установлен.\n\nУбедитесь в том, что канюля установлена правильно и замените Pod, если такой уверенности нет. - Деактивировать Pod - \nНажмите Далее для деактивации Пода\n\nПримечание: Это Приостановит всякую подачу инсулина и деактивирует помпу. - Деактивация помпы - Деактивация помпы.\n\n, Когда проверены все элементы, нажмите Далее.\n\nПримечание: Если деактивация постоянно завершается ошибкой, нажмите Отменить и примените Сброс помпы чтобы принудительно сбросить состояние Pod\'a. - Pod деактивирован.\n\nУдалите и утилизируйте Pod. - Сопряжение Pod - Заполнение инфузионной секции Pod\'a - Заполнение катетера - Задан профиль базала - Отмена подачи инсулина - Деактивировать Pod - - - Интеграция с помпой Omnompod Dash. - Напоминание о завершении сопряжения - Напоминание о завершении настройки - Срок работы Pod\'a истекает - Срок Pod\'a истекает в ближайшее время - Остановка неизбежна - В резервуаре мало инсулина - Неизвестное оповещение - Возможно, не удалось задать базовый профиль. Подача инсулина может быть приостановлена! Обновите состояние Pod. - Возможно, установка временного базала не удалась. Если временный базал уже работал, возможна его отмена! Обновите статус Pod\'a. - Возможно, не удалось задать время. Подача инсулина может быть приостановлена! Обновите состояние Pod. - Не удалось проверить правильность подачи болюса. Убедитесь, что Pod подает болюс или отмените его. - Статистика RL - Журнал Pulse Сравнить профили Помощник профиля Профиль по умолчанию diff --git a/app/src/main/res/values-sk-rSK/strings.xml b/app/src/main/res/values-sk-rSK/strings.xml index 68b8313891..a10a53eb76 100644 --- a/app/src/main/res/values-sk-rSK/strings.xml +++ b/app/src/main/res/values-sk-rSK/strings.xml @@ -559,6 +559,7 @@ Pumpa nedostupná Chýbajúce hodnoty glykémie Používať systémové notifikácie pre výstrahy a oznámenia + Postupne zvyšovať hlasitosť upozornení a oznámení Lokálne výstrahy Výstraha pri nedostupných hodnotách glykémie Výstraha pri nedostupnej pumpe @@ -1082,7 +1083,6 @@ Vymazanie dokončené Vymazanie začaté Chcete resetovať začiatok cieľa? Môžete prísť o svoj pokrok. - Zmena času a/alebo časovej zóny na pumpe Nie je vybraná žiadna pumpa Vyberte jednotky, v ktorých chcete zobraziť hodnoty Odoslať zmeny lokálneho profilu do NS @@ -1159,7 +1159,6 @@ Autorizácia zlyhala Celkový inzulín Hlavné heslo sa používa na šifrovanie zálohy a na \"prebitie\" zabezpečenia v aplikácii. Dobre si ho zapamätajte, alebo uložte na bezpečnom mieste. - Heslá sa nezhodujú Aktuálne hlavné heslo Indikátory stavu Kopírovať nastavenia z NS @@ -1168,123 +1167,6 @@ Tlačidlá sú vždy zobrazené v spodnej časti obrazovky Veľký displej Vzhľad - - Nikdy nepripojené - Prebúdzanie - Chyba komunikácie - Uplynul časový limit komunikácie - Pumpa nedostupná - Neplatná konfigurácia - Aktívna - Spiaca - - - Integrácia pumpy pre Omnipod, vyžaduje zariadenie RileyLink (s firmwarom aspoň 2.0). - - Pípnutie pri boluse povolené - Pípnutie pri bazále povolené - Pípnutie pri SMB povolené - Pípnutie pri TBR povolené - Možnosti ladenia Podu povolené - Letný čas / Detekcia časového pásma povolená - - Správa Podu - Stav Podu - Zostáva %1$.2f JI - Viac ako 50 JI - Adresa Podu - Expirácia Podu - Žiadne info - Žiadny Pod nie je pripojený - Nie je inicializovaný - Výstrahy aktívneho Podu - Potvrdiť výstrahu - - Omnipod (433,91 MHz) - - Operácia nie je možná.\n\nNajskôr je nutné nakonfigurovať Omnipod, kým bude možné túto funkciu použiť. - Operácia nie je možná.\n\n Je potrebné niekoľko minút počkať, pokiaľ sa AAPS nepokúsi prvý krát nastaviť profil. - Neplatný atribút PodInitActionType: %1$s - Žiadny aktívny Pod. - Overenie príkazu zlyhalo. - Došlo k neočakávanej chybe. Nahláste ju! (typ: %1$s). - Komunikácia zlyhala: boli prijaté neplatné vstupné parametre. - Komunikácia zlyhala: časový limit vypršal. - Komunikácia zlyhala: vyskytla sa neočakávaná chyba. Prosím, nahláste to! - Komunikácia zlyhala: overenie integrity správy zlyhalo. - Komunikácia zlyhala: boli prijaté neplatné pakety z Podu. - Komunikácia zlyhala: Pod je v chybnom stave. - Komunikácia zlyhala: bola prijatá neplatná odozva z Podu. - Komunikácia zlyhala: bola prijatá správa s neplatným poradovým číslom z Podu. - Komunikácia zlyhala: bola prijatá správa s neplatnou adresou z Podu. - Komunikácia zlyhala: nepodarilo se dekódovať správu z Podu. - Komunikácia zlyhala: opakovaná synchronizácia Nonce hodnoty zlyhala. - Komunikácia zlyhala: hodnota Nonce nebola synchronizovaná. - Komunikácia zlyhala: nedostatok dát prijatých z Podu. - Bola zistená chyba Podu (%1$03d %2$s). Deaktivujte Pod a spustite nový. - Komunikácia zlyhala: Pod vrátil chybovú odozvu. - - Správa Podu - Inicializovať Pod - Deaktivovať Pod - Resetovať Pod - História Podu - Nastaviť bolus - Zrušiť bolus - Nastaviť dočasný bazál - Zrušiť dočasný bazál (interne ovládačom) - Zrušiť dočasný bazál (nútene užívateľom) - Nastaviť plán bazálu - Zistiť stav Podu - Zistiť informácie o Pode - Nastaviť čas - Nastaviť výstrahy - Potvrdiť výstrahy - Pozastaviť dodávanie inzulínu - Pokračovať v dodávaní inzulínu - Neznáma položka - %1$.1f JI - %1$.1f JI, CH=%2$.1f g - Rýchlosť: %1$.1f JI, Doba trvania: %2$d min - Keď stlačíš OK, bude pripojenie na Pod nútene prerušené a nebudete sa môcť k nemu už viac pripojiť. Urob tak iba vtedy, ak AAPS nemôže viac komunikovať s Podom. Ak stále môžete komunikovať s Podom, prosím použite možnosť Deaktivovať Pod. - História Podu momentálne nie je dostupná. - Naplňte Pod - \nNaplňte Pod dostatočným množstvom inzulínu na 3 dni.\n\nPočúvaj aj dve pípnutia počas plnenia. Tieto poukazujú na to, že Pod bol naplnený minimálnym množstvom 85 JI. Úplne vyprázdni striekačku, aj keď si počul dve pípnutia.\n\nKlikni <bĎalej</b> po tom, čo si naplnil Pod.\n\n<b>Poznámka:</b> Neodstraňuj ešte ochranu ihly na Pode. - Plnenie - Pokús sa spárovať s novým Podom a naplň ho.\n\nKeď sú všetky položky zaškrtnuté, môžete stlačiť Ďalej.\n\nPoznámka: prosím držte teraz Pod veľmi blízko RileyLinku. - Pripevni Pod - \nPripravte infúzny set. Odstráňte krytku ihly na Pode a ochranu samolepky a pripojte Pod k infúznemu setu. \n\nAk sa kanyla odlepí, prosím stlačte Zrušiť a zahoďte Váš Pod.\n\nStlačte Ďalšia na zavedenie kanyly a začiatok podávania bazálu. - Zavedenie kanyly - Pokúšam sa nastaviť počiatočnú bazálnu dávku a zaviesť kanylu.\n\nAk sú všetky položky označené, môžete stlačiť Ďalší. - Informácie o Pode - \nPod je teraz aktívny.\n\nVaša bazálna dávka je nastavená a kanyla bola zavedená.\n\nProsím skontrolujte, či bola kanyla zavedená správne a ak máte pocit, že nie, tak vymeňte Pod. - Deaktivovať Pod - \nStlačte Ďalej pre deaktiváciu Podu.\n\nPoznámka: Toto preruší celkovo podávanie inzulínu a deaktivuje Pod. - Deaktivácia Podu - Deaktivujem Pod.\n\nKeď sú všetky položky zaškrtnuté, môžete stlačiť Ďalej.\n\nPoznámka: Ak deaktivácia neustále zlyháva, stlačte prosím Zrušiť a použite možnosť Resetovať Pod, na nútené obnovenie stavu Podu. - Pod deaktivovaný.\n\nProsím odstráňte Pod z Vášho tela a zlikvidujte ho. - Spárujte Pod - Naplňte Pod - Naplňte kanylu - Nastavte bazálny profil - Zrušte podávanie - Deaktivujte Pod - - - Integrácia pumpy pre Omnipod Dash. - Pripomienka ukončenia párovania - Pripomienka ukončenia nastavenia - Pod čoskoro expiruje - Pod čoskoro expiruje - Vypnutie je bezprostredné - Nízka hladina zásobníka - Neznáma výstraha - Nastavenie bazálu mohlo zlyhať. Podávanie môže byť pozastavené! Prosím, obnovte stav Podu. - Nastavenie dočasného bazálu mohlo zlyhať. Ak už bol spustený dočasný bazál, mohol byť zrušený! Prosím, obnovte stav Podu. - Nastavenie času mohlo zlyhať. Podávanie môže byť pozastavené! Prosím, obnovte stav Podu. - Nie je možné overiť, či bolo podávanie bolusu úspešné. Prosím overte, že váš Pod podáva bolus, alebo zrušte bolus. - Štatistiky RL - Pulse Log Porovnať profily Pomocník s profilom Predvolený profil diff --git a/app/src/main/res/values-sl-rSI/strings.xml b/app/src/main/res/values-sl-rSI/strings.xml index 2578fce6a9..1ce4989b86 100644 --- a/app/src/main/res/values-sl-rSI/strings.xml +++ b/app/src/main/res/values-sl-rSI/strings.xml @@ -5,14 +5,4 @@ - - - - - - - - - - diff --git a/app/src/main/res/values-sv-rSE/strings.xml b/app/src/main/res/values-sv-rSE/strings.xml index e17e7d055c..6b84159dea 100644 --- a/app/src/main/res/values-sv-rSE/strings.xml +++ b/app/src/main/res/values-sv-rSE/strings.xml @@ -61,7 +61,7 @@ Eversense-appen. IOB fr basal: BG TT - KH + Kolhydrater Korrektion Bolus IOB Utför nu @@ -149,7 +149,7 @@ Eversense-appen. Procent Absolut Anteckning - Tid för händelse + När Profil Loggat av Glukostyp @@ -157,6 +157,7 @@ Eversense-appen. Temp basal Förlängd bolus Nightscoutversion: + Saknar %1$dg Inställningar exporterade Exportera inställningar till Importera inställningar från @@ -235,6 +236,10 @@ Eversense-appen. Minsta antal minuter som måste förflyta mellan en fjärrbolus och nästa Minsta antal minuter mellan fjärrbolus För att redigera den här inställningen måste du, för din säkerhet, lägga till minst 2 telefonnummer. + Bolus %1$.2f enheter levererat + Kommer att leverera %1$.2f enheter + Bolus %1$.2f enheter levererat + Bolus på %1$.2f enheter levererat Temporärt mål på %1$s är satt i %2$d minuter Temporärt mål på %1$s är satt i %2$d minuter Temporärt mål avbrutet @@ -258,7 +263,9 @@ Eversense-appen. Pump återansluten Otillåtet fjärrkommando Fjärrbolus inte tillgängligt. Försök igen senare. + För att starta temp basal %1$.2f enheter/tim i %2$d min, svara med kod %3$s För att byta till profil %1$s %2$d%% svara med kod %3$s + För att starta förlängd bolus med %1$.2f enheter över %2$d min, svara med kod %3$s Om du vill ange %1$dg kl. %2$s, svara med kod %3$s För att starta temp basal %1$d%% i %2$d min, svara med kod %3$s För att pausa loop i %1$d minuter, svara med kod %2$s @@ -267,6 +274,7 @@ Eversense-appen. För att inaktivera loopen, svara med kod %1$s Temp basal %1$.2f enheter/tim i %2$d min startad Förlängd bolus %1$.2f enheter över %2$d min har startats + %1$dg kolhydrater registrerat Misslyckades med att registrera %1$dg kolhydrater Temp basal %1$d%% enheter/tim i %2$d min startad Fel vid start av temp basal @@ -835,7 +843,7 @@ Eversense-appen. Fel på NSClient. Överväg att starta om NSClient och Nightscout-webbplatsen. AS Version %1$s tillgänglig - Tidsförskjutning + KH-tid Föredraget APS-läge Total Kalkyl @@ -847,6 +855,7 @@ Eversense-appen. Stämmer koderna överens mellan denna enhet och din pump? Parkoppling av Insight Accu-Chek Insight + %1$.2fU / %2$.2fU levererat %1$s: %2$s Slang bytt Tiden uppdaterad i pumpen @@ -904,6 +913,7 @@ Eversense-appen. Förl: %1$.2f / %2$.2f U i %3$d min Kombi: %1$.2f / %2$.2f U i %3$d min TDD: %1$.2f + Res: %1$.2fU Batt.: %1$d%% Max paus mellan återanslutningsförsök [s] Min paus mellan återanslutningsförsök [s] @@ -1046,6 +1056,8 @@ Eversense-appen. Skicka SMS: %1$s Skicka SMS till alla nummer Skicka SMS med text + COB kontra IOB + Bolusbegränsning tillämpad: %1$.2f U till %2$.2f U Varning! Långsam KH-absorption upptäckt %2$d%% av tiden. Dubbelkolla din beräkning. COB kan vara väldigt missvisande och du riskerar få för mycket insulin!]]> Direkt bolus [%] Bolusguiden utför beräkningar, men endast denna del av beräknat insulin levereras. Användbar med SMB-algoritm. @@ -1071,7 +1083,6 @@ Eversense-appen. Rensa avslutade Rensa påbörjade Vill du starta om målet? Du kan förlora de steg du gjort hittills. - Tid och/eller tidszonsändring på pump Ingen pump har valts Välj enheter du vill visa värden i Överför lokala profiländringar till NS @@ -1148,7 +1159,6 @@ Eversense-appen. Behörighetskontroll misslyckades Absolut insulinmängd Huvudlösenordet används för att kryptera backuper och för att åsidosätta vissa säkerhetsfunktioner i applikationen. Kom ihåg det eller förvara det på ett säkert ställe. - Lösenorden stämmer inte överens Nuvarande huvudlösenord Statuslampor Kopiera inställningar från NS @@ -1157,123 +1167,6 @@ Eversense-appen. Knappar visas alltid längst ned på skärmen Stor skärm Tema - - Aldrig ansluten - Väcker - Kommunikationsfel - Kommunikationstimeout - Pumpen kan inte nås - Felaktig konfigureration - Aktiv - Sover - - - Pumpintegrering för Omnipod. Kräver Riley Link med minst v2-firmware. - - Boluspip aktiverade - Basalpip aktiverade - SMB-pip aktiverade - Tempbasal-pip aktiverade - Debug-alternativ aktiverade för pod - Automatisk avkänning av tidszon aktiverad - - Omnipod - Pod-status - %1$.2f U återstår - Över 50 U - Podadress - Pod går ut - Ingen info - Ingen pod ansluten - Inte initierad - Aktiva pod-varningar - Ack-varningar - - Omnipod (433.91 MHz) - - Operationen inte möjlig.\n\n Du måste konfigurera Omnipod innan du kan använda denna funktion. - Operationen är inte möjlig.\n\n Du måste vänta några minuter, tills AAPS försöker ställa in profilen för första gången. - Ogiltig PodInitActionType: %1$s - Ingen aktiv pod. - Kommandoverifikation misslyckades. - Ett oväntat fel uppstod. Vänligen rapportera! (typ: %1$s). - Kommunikationsfel: Emottog ogiltiga indataparametrar. - Kommunikationsfel: Timeout. - Kommunikationsfel: Ett oväntat fel inträffade. Rapportera! - Kommunikationsfel: Lyckades inte verifiera meddelandet. - Kommunikationsfel: Mottog ett ogiltigt datapaket från pod. - Kommunikationsfel: Pod är i fel tillstånd. - Kommunikationsfel: Mottog ett felaktig svar från pod. - Kommunikationsfel: Tog emot ett meddelande med ett ogiltigt sekvensnummer från podden. - Kommunikationsfel: Tog emot ett meddelande med en ogiltig adress från podden. - Kommunikationsfel: Misslyckades avkoda meddelandet från pod. - Kommunikationsfel: \"nonce resync\" misslyckades. - Kommunikationsfel: \"nonce\" är inte i synk. - Kommunikationsfel: Mottog inte tillräckligt mycket data från pod. - Ett pod-fel (%1$03d %2$s) har upptäckts. Vänligen inaktivera din pod och starta en ny. - Kommunikationsfel: Pod returnerade ett fel. - - Podhantering - Initiera pod - Inaktivera pod - Återställ pod - Pod-historik - Leverera bolus - Avbryt Bolus - Sätt temp basal - Avbryt temp basal (internt av drivrutinen) - Avbryt temp basal (tvingat av användaren) - Ange basaldoser - Uppdatera pod-status - Hämta Pod-information - Ställ in tid - Konfigurera varningar - Bekräfta varningar - Pausa insulintillförsel - Återuppta insulintillförsel - Okänd post - %1$.1f U - %1$.1f U, KH=%2$.1f g - Dos: %1$.1f U, Duration: %2$d min - Om du trycker på OK, kommer poddstatus att tvångsåterställas och du kommer inte att kunna kommunicera med podden längre. Gör det här bara om du inte kan kommunicera med podden. Om du fortfarande kan kommunicera med den, använd alternativet Inaktivera pod. - Pod-historik är inte tillgänglig för tillfället. - Fyll pod - \nFyll den nya podden med tillräckligt med insulin för 3 dagar.\n\nLyssna efter två pip under påfyllningsprocessen. Dessa anger att minimimängden 85U har nåtts. Var noga med att helt tömma påfyllningssprutan, även efter att ha hört de två pipen.\n\nNär påfyllningen är klar, tryck Nästa.\n\nNotera: Ta inte bort nålskyddet ännu. - Förfyllning - Försöker parkoppla den nya podden och förfylla den.\n\nNär alla steg är sluförda, kan du trycka på Nästa.\n\nNotera: Håll din riley link väldigt nära podden. - Fäst podden - \nFörbered infusionsplatsen. Ta bort poddens nålskydd och fäst podden på infusionsplatsen.\n\nOm kanylen sticker ut, tryck på Avbryt och kasta din pod.\n\nTryck Nästa för att skjuta in kanylen och påbörja basaldoseringen. - Skjuter in kanylen - Försöker att ställa in basaldoser och skjuta in kanylen.\n\nNär alla steg är slutförda, kan du trycka på Nästa. - Pod-info - \nPodden är nu aktiverad.\n\nDina basaldoser har programmerats och kanylen har skjutits in in.\n\nKontrollera att kanylen sitter på rätt sätt och byt pod om den inte gjort det. - Inaktivera pod - \nTryck på Nästa för att inaktivera podden.\n\nOBS! Det här stoppar all insulintillförsel och inaktiverar podden. - Inaktiverar pod - Inaktivering av pod\n\nNär alla steg är slutförda, kan du trycka på Nästa.\n\nNotera: Om inaktivering misslyckas ofta, tryck på Avbryt och använd alternativet Återställ pod för att tvångsåterställa podden. - Pod inaktiverad.\n\nTa bort podden och kasta den. - Parkoppla pod - Förfyll pod - Fyll kanyl - Sätt basalprofil - Avbryt leverans - Inaktivera pod - - - Pumpintegration för Omnipod Dash. - Påminnelse att slutföra parkoppling - Påminnelse att slutföra installation - Pod löper snart ut - Pod kommer att gå ut inom kort - Pod kommer snart att stängas av - Låg reservoar - Okänd varning - Inställning av basalprofil kan ha misslyckats. Leverans kan avbrytas! Vänligen uppdatera pod-status. - Inställning av temp basal kan ha misslyckats. Om det redan var en temp basal igång, kan den ha avbrutits! Vänligen uppdatera pod-status. - Tidsuppdateringen kan ha misslyckats. Leverans kan avbrytas! Vänligen uppdatera pod-status. - Det går inte att verifiera om bolusen är slutförd. Verifiera att din pod leverarar bolus eller avsluta bolus. - RL-statistik - Pulslogg Jämför profiler Profilguide Standardprofil diff --git a/app/src/main/res/values-tr-rTR/strings.xml b/app/src/main/res/values-tr-rTR/strings.xml index aa1332bb29..0c525f3183 100644 --- a/app/src/main/res/values-tr-rTR/strings.xml +++ b/app/src/main/res/values-tr-rTR/strings.xml @@ -682,14 +682,4 @@ Aktif Karbonhidratın ne kadar hızlı sindirildiğine ve KŞ\'nin beklenenden d Tomato (MiaoMiao) Tomato - - - - - - - - - - diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 41c36951a1..ec2b5760b4 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -800,14 +800,4 @@ DXCM 从补丁版的德康APP收到血糖值 - - - - - - - - - - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d3bd9b86bf..a804dc395d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -657,6 +657,7 @@ Missed BG readings raise_urgent_alarms_as_android_notification Use system notifications for alerts and notifications + Gradually increase the volume for alerts and notifications enable_pump_unreachable_alert enable_missed_bg_readings enable_carbs_required_alert_local @@ -665,8 +666,6 @@ Alert if pump is unreachable Pump unreachable threshold [min] Alert if carbs are required - pump_unreachable_threshold - missed_bg_readings_threshold Urgent Alarm INFO Eversense App (patched) diff --git a/app/src/main/res/xml/pref_alerts.xml b/app/src/main/res/xml/pref_alerts.xml index a7783f7954..77c9b126d8 100644 --- a/app/src/main/res/xml/pref_alerts.xml +++ b/app/src/main/res/xml/pref_alerts.xml @@ -16,7 +16,7 @@ android:defaultValue="30" android:dependency="@string/key_enable_missed_bg_readings_alert" android:inputType="number" - android:key="@string/key_missed_bg_readings_threshold" + android:key="@string/key_missed_bg_readings_threshold_minutes" android:title="@string/nsalarm_staledatavalue_label" validate:maxNumber="10000" validate:minNumber="15" @@ -36,7 +36,7 @@ android:defaultValue="30" android:dependency="@string/key_enable_pump_unreachable_alert" android:inputType="number" - android:key="@string/key_pump_unreachable_threshold" + android:key="@string/key_pump_unreachable_threshold_minutes" android:title="@string/pump_unreachable_threshold" validate:maxNumber="300" validate:minNumber="30" @@ -47,6 +47,11 @@ android:key="@string/key_raise_notifications_as_android_notifications" android:title="@string/raise_notifications_as_android_notifications" /> + + diff --git a/core/src/main/java/info/nightscout/androidaps/Constants.java b/core/src/main/java/info/nightscout/androidaps/Constants.java index f66342de7e..474addaa38 100644 --- a/core/src/main/java/info/nightscout/androidaps/Constants.java +++ b/core/src/main/java/info/nightscout/androidaps/Constants.java @@ -89,6 +89,9 @@ public class Constants { // Local profile public static final String LOCAL_PROFILE = "LocalProfile"; + // Local Alerts + public static final int DEFAULT_PUMP_UNREACHABLE_THRESHOLD_MINUTES = 30; + public static final int DEFAULT_MISSED_BG_READINGS_THRESHOLD_MINUTES = 30; // One Time Password diff --git a/core/src/main/java/info/nightscout/androidaps/data/Profile.java b/core/src/main/java/info/nightscout/androidaps/data/Profile.java index 9fe8c7846e..f71e53e9b6 100644 --- a/core/src/main/java/info/nightscout/androidaps/data/Profile.java +++ b/core/src/main/java/info/nightscout/androidaps/data/Profile.java @@ -544,6 +544,10 @@ public class Profile { return getValueToTime(targetLow_v, timeAsSeconds); } + public double getTargetLowMgdlTimeFromMidnight(int timeAsSeconds) { + return toMgdl(getTargetLowTimeFromMidnight(timeAsSeconds), units); + } + public double getTargetHighMgdl() { return toMgdl(getTargetHighTimeFromMidnight(secondsFromMidnight()), units); } @@ -558,6 +562,10 @@ public class Profile { return getValueToTime(targetHigh_v, timeAsSeconds); } + public double getTargetHighMgdlTimeFromMidnight(int timeAsSeconds) { + return toMgdl(getTargetHighTimeFromMidnight(timeAsSeconds), units); + } + public class TargetValue { TargetValue(int timeAsSeconds, double low, double high) { this.timeAsSeconds = timeAsSeconds; diff --git a/core/src/main/java/info/nightscout/androidaps/db/CareportalEvent.java b/core/src/main/java/info/nightscout/androidaps/db/CareportalEvent.java index 80a72ada37..22768183a3 100644 --- a/core/src/main/java/info/nightscout/androidaps/db/CareportalEvent.java +++ b/core/src/main/java/info/nightscout/androidaps/db/CareportalEvent.java @@ -78,6 +78,18 @@ public class CareportalEvent implements DataPointWithLabelInterface, Interval { public static final String MBG = "Mbg"; // comming from entries + // found in CareDialog.kt file + public static final String FINGER = "Finger"; + public static final String SENSOR = "Sensor"; + public static final String MANUAL = "Manual"; + + // found in Translator.kt + public static final String SNACKBOLUS = "Snack Bolus"; + public static final String SENSORSTART = "Sensor Start"; + public static final String TEMPBASALSTART = "Temp Basal Start"; + public static final String TEMPBASALEND = "Temp Basal End"; + public static final String TEMPBASALCANCEL = "Temporary Target Cancel"; + @Deprecated public CareportalEvent() { StaticInjector.Companion.getInstance().androidInjector().inject(this); diff --git a/core/src/main/java/info/nightscout/androidaps/db/TemporaryBasal.java b/core/src/main/java/info/nightscout/androidaps/db/TemporaryBasal.java index 660ec0ad0a..012016ee03 100644 --- a/core/src/main/java/info/nightscout/androidaps/db/TemporaryBasal.java +++ b/core/src/main/java/info/nightscout/androidaps/db/TemporaryBasal.java @@ -262,7 +262,7 @@ public class TemporaryBasal implements Interval, DbObjectBase { double dia = profile.getDia(); double dia_ago = time - dia * 60 * 60 * 1000; int aboutFiveMinIntervals = (int) Math.ceil(realDuration / 5d); - double tempBolusSpacing = realDuration / aboutFiveMinIntervals; + double tempBolusSpacing = (double) (realDuration / aboutFiveMinIntervals); for (long j = 0L; j < aboutFiveMinIntervals; j++) { // find middle of the interval diff --git a/core/src/main/java/info/nightscout/androidaps/dialogs/ProfileViewerDialog.kt b/core/src/main/java/info/nightscout/androidaps/dialogs/ProfileViewerDialog.kt index b3286cb590..d95a95550b 100644 --- a/core/src/main/java/info/nightscout/androidaps/dialogs/ProfileViewerDialog.kt +++ b/core/src/main/java/info/nightscout/androidaps/dialogs/ProfileViewerDialog.kt @@ -14,7 +14,9 @@ import info.nightscout.androidaps.core.R import info.nightscout.androidaps.data.Profile import info.nightscout.androidaps.interfaces.ActivePluginProvider import info.nightscout.androidaps.interfaces.DatabaseHelperInterface +import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.utils.DateUtil +import info.nightscout.androidaps.utils.DecimalFormatter import info.nightscout.androidaps.utils.HtmlHelper import info.nightscout.androidaps.utils.resources.ResourceHelper import kotlinx.android.synthetic.main.close.* @@ -28,6 +30,7 @@ class ProfileViewerDialog : DaggerDialogFragment() { @Inject lateinit var resourceHelper: ResourceHelper @Inject lateinit var activePlugin: ActivePluginProvider @Inject lateinit var dateUtil: DateUtil + @Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var databaseHelper: DatabaseHelperInterface private var time: Long = 0 @@ -85,7 +88,7 @@ class ProfileViewerDialog : DaggerDialogFragment() { profileview_datelayout.visibility = View.VISIBLE } - Mode.CUSTOM_PROFILE -> { + Mode.CUSTOM_PROFILE -> { profile = Profile(injector, JSONObject(customProfileJson), customProfileUnits) profile2 = null profileName = customProfileName @@ -102,7 +105,7 @@ class ProfileViewerDialog : DaggerDialogFragment() { profileview_datelayout.visibility = View.GONE } - Mode.DB_PROFILE -> { + Mode.DB_PROFILE -> { val profileList = databaseHelper.getProfileSwitchData(time, true) profile = if (profileList.isNotEmpty()) profileList[0].profileObject else null profile2 = null @@ -116,7 +119,7 @@ class ProfileViewerDialog : DaggerDialogFragment() { if (mode == Mode.PROFILE_COMPARE) profile?.let { profile1 -> profile2?.let { profile2 -> - profileview_units.text = profile1.units + profileview_units.text = profileFunction.getUnits() profileview_dia.text = HtmlHelper.fromHtml(formatColors("", profile1.dia, profile1.dia, DecimalFormat("0.00"), resourceHelper.gs(R.string.shorthour))) val profileNames =profileName!!.split("\n").toTypedArray() profileview_activeprofile.text = HtmlHelper.fromHtml(formatColors(profileNames[0], profileNames[1])) @@ -124,7 +127,7 @@ class ProfileViewerDialog : DaggerDialogFragment() { profileview_ic.text = ics(profile1, profile2) profileview_isf.text = isfs(profile1, profile2) profileview_basal.text = basals(profile1, profile2) - profileview_target.text = HtmlHelper.fromHtml(formatColors("", profile1.targetList.replace("\n","
") + "
", profile2.targetList.replace("\n","
"), "")) + profileview_target.text = targets(profile1, profile2) basal_graph.show(profile1, profile2) } @@ -223,23 +226,50 @@ class ProfileViewerDialog : DaggerDialogFragment() { prev1 = val1 prev2 = val2 } - return HtmlHelper.fromHtml(s.toString()) + return HtmlHelper.fromHtml(s.delete(s.length-4, s.length).toString()) } private fun isfs(profile1: Profile, profile2: Profile): Spanned { var prev1 = 0.0 var prev2 = 0.0 + val units = profileFunction.getUnits() val s = StringBuilder() for (hour in 0..23) { - val val1 = Profile.fromMgdlToUnits(profile1.getIsfMgdlTimeFromMidnight(hour * 60 * 60), profile1.units) - val val2 = Profile.fromMgdlToUnits(profile2.getIsfMgdlTimeFromMidnight(hour * 60 * 60), profile1.units) + val val1 = Profile.fromMgdlToUnits(profile1.getIsfMgdlTimeFromMidnight(hour * 60 * 60), units) + val val2 = Profile.fromMgdlToUnits(profile2.getIsfMgdlTimeFromMidnight(hour * 60 * 60), units) if (val1 != prev1 || val2 != prev2) { - s.append(formatColors(Profile.format_HH_MM(hour * 60 * 60), val1, val2, DecimalFormat("0.0"), profile1.units + " " + resourceHelper.gs(R.string.profile_per_unit))) + s.append(formatColors(Profile.format_HH_MM(hour * 60 * 60), val1, val2, DecimalFormat("0.0"), units + " " + resourceHelper.gs(R.string.profile_per_unit))) s.append("
") } prev1 = val1 prev2 = val2 } - return HtmlHelper.fromHtml(s.toString()) + return HtmlHelper.fromHtml(s.delete(s.length-4, s.length).toString()) + } + + private fun targets(profile1: Profile, profile2: Profile):Spanned { + var prev1l = 0.0 + var prev1h = 0.0 + var prev2l = 0.0 + var prev2h = 0.0 + val units = profileFunction.getUnits() + val s = StringBuilder() + for (hour in 0..23) { + val val1l = profile1.getTargetLowMgdlTimeFromMidnight(hour * 60 * 60) + val val1h = profile1.getTargetHighMgdlTimeFromMidnight(hour * 60 * 60) + val val2l = profile2.getTargetLowMgdlTimeFromMidnight(hour * 60 * 60) + val val2h = profile2.getTargetHighMgdlTimeFromMidnight(hour * 60 * 60) + val txt1 = Profile.format_HH_MM(hour * 60 * 60) + " " + Profile.toUnitsString(val1l, val1l * Constants.MGDL_TO_MMOLL, units) + " - " + Profile.toUnitsString(val1h, val1h * Constants.MGDL_TO_MMOLL, units) + " " + units + val txt2 = Profile.format_HH_MM(hour * 60 * 60) + " " + Profile.toUnitsString(val2l, val2l * Constants.MGDL_TO_MMOLL, units) + " - " + Profile.toUnitsString(val2h, val2h * Constants.MGDL_TO_MMOLL, units) + " " + units + if (val1l != prev1l || val1h != prev1h || val2l != prev2l || val2h != prev2h ) { + s.append(formatColors(txt1, txt2)) + s.append("
") + } + prev1l = val1l + prev1h = val1h + prev2l = val2l + prev2h = val2h + } + return HtmlHelper.fromHtml(s.delete(s.length-4, s.length).toString()) } } diff --git a/core/src/main/java/info/nightscout/androidaps/interfaces/DatabaseHelperInterface.kt b/core/src/main/java/info/nightscout/androidaps/interfaces/DatabaseHelperInterface.kt index 007ff88b90..aea3be7fee 100644 --- a/core/src/main/java/info/nightscout/androidaps/interfaces/DatabaseHelperInterface.kt +++ b/core/src/main/java/info/nightscout/androidaps/interfaces/DatabaseHelperInterface.kt @@ -24,6 +24,7 @@ interface DatabaseHelperInterface { fun getTemporaryBasalsDataFromTime(mills: Long, ascending: Boolean): List fun getCareportalEventFromTimestamp(timestamp: Long): CareportalEvent? fun getAllOmnipodHistoryRecordsFromTimestamp(timestamp: Long, ascending: Boolean): List + fun findOmnipodHistoryRecordByPumpId(pumpId: Long): OmnipodHistoryRecord? fun getTDDsForLastXDays(days: Int): List fun getProfileSwitchData(from: Long, ascending: Boolean): List } diff --git a/core/src/main/java/info/nightscout/androidaps/interfaces/PumpDescription.java b/core/src/main/java/info/nightscout/androidaps/interfaces/PumpDescription.java index 76c6253160..92de42542a 100644 --- a/core/src/main/java/info/nightscout/androidaps/interfaces/PumpDescription.java +++ b/core/src/main/java/info/nightscout/androidaps/interfaces/PumpDescription.java @@ -11,11 +11,11 @@ import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; public class PumpDescription { public PumpType pumpType = PumpType.GenericAAPS; - public PumpDescription () { + public PumpDescription() { resetSettings(); } - public PumpDescription (PumpType pumpType) { + public PumpDescription(PumpType pumpType) { this(); setPumpDescription(pumpType); } @@ -52,6 +52,7 @@ public class PumpDescription { public double basalMaximumRate; public boolean isRefillingCapable; + public boolean isBatteryReplaceable; public boolean storesCarbInfo; @@ -88,7 +89,8 @@ public class PumpDescription { basalMaximumRate = 25d; is30minBasalRatesCapable = false; - isRefillingCapable = false; + isRefillingCapable = true; + isBatteryReplaceable = true; storesCarbInfo = true; supportsTDDs = false; @@ -136,6 +138,7 @@ public class PumpDescription { basalMinimumRate = pumpType.getBaseBasalMinValue(); isRefillingCapable = pumpCapability.hasCapability(PumpCapability.Refill); + isBatteryReplaceable = pumpCapability.hasCapability(PumpCapability.ReplaceBattery); storesCarbInfo = pumpCapability.hasCapability(PumpCapability.StoreCarbInfo); supportsTDDs = pumpCapability.hasCapability(PumpCapability.TDD); diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/PointsWithLabelGraphSeries.java b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/PointsWithLabelGraphSeries.java index 8058a6eef6..edf003e859 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/PointsWithLabelGraphSeries.java +++ b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/graphExtensions/PointsWithLabelGraphSeries.java @@ -264,7 +264,7 @@ public class PointsWithLabelGraphSeries e Rect bounds = new Rect(); mPaint.getTextBounds(value.getLabel(), 0, value.getLabel().length(), bounds); mPaint.setStyle(Paint.Style.STROKE); - float px = endX + bounds.height() / 2; + float px = endX + bounds.height() / 2.0f; float py = (float) (graphHeight * ratY + bounds.width() + 10); canvas.save(); canvas.rotate(-90, px, py); diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.java b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.java index b43b058277..b4d91226ee 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.java +++ b/core/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.java @@ -72,6 +72,8 @@ public class Notification { public static final int OMNIPOD_POD_NOT_ATTACHED = 59; public static final int CARBS_REQUIRED = 60; public static final int IMPORTANCE_HIGH = 2; + public static final int OMNIPOD_POD_SUSPENDED = 61; + public static final int OMNIPOD_POD_ALERTS_UPDATED = 62; public static final String CATEGORY_ALARM = "alarm"; diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/PumpPluginAbstract.java b/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/PumpPluginAbstract.java index c45036df73..7b353b2e5c 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/PumpPluginAbstract.java +++ b/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/PumpPluginAbstract.java @@ -474,8 +474,4 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI return new PumpEnactResult(getInjector()).success(false).enacted(false).comment(getResourceHelper().gs(resourceId)); } - protected FabricPrivacy getFabricPrivacy() { - return this.fabricPrivacy; - } - } diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpCapability.java b/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpCapability.java index 8917d3e834..0f8baa6392 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpCapability.java +++ b/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpCapability.java @@ -11,18 +11,19 @@ public enum PumpCapability { TempBasal, // isTempBasalCapable BasalProfileSet, // isSetBasalProfileCapable Refill, // isRefillingCapable + ReplaceBattery, // isBatteryReplaceable StoreCarbInfo, // storesCarbInfo TDD, // supportsTDDs ManualTDDLoad, // needsManualTDDLoad BasalRate30min, // is30minBasalRatesCapable // grouped by pump - VirtualPumpCapabilities(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill), // - ComboCapabilities(Bolus, TempBasal, BasalProfileSet, Refill, TDD, ManualTDDLoad), // - DanaCapabilities(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill, TDD, ManualTDDLoad), // - DanaWithHistoryCapabilities(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill, StoreCarbInfo, TDD, ManualTDDLoad), // - InsightCapabilities(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill,TDD,BasalRate30min), // - MedtronicCapabilities(Bolus, TempBasal, BasalProfileSet, Refill, TDD), // + VirtualPumpCapabilities(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill, ReplaceBattery), // + ComboCapabilities(Bolus, TempBasal, BasalProfileSet, Refill, ReplaceBattery, TDD, ManualTDDLoad), // + DanaCapabilities(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill, ReplaceBattery, TDD, ManualTDDLoad), // + DanaWithHistoryCapabilities(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill, ReplaceBattery, StoreCarbInfo, TDD, ManualTDDLoad), // + InsightCapabilities(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill, ReplaceBattery, TDD, BasalRate30min), // + MedtronicCapabilities(Bolus, TempBasal, BasalProfileSet, Refill, ReplaceBattery, TDD), // OmnipodCapabilities(Bolus, TempBasal, BasalProfileSet, BasalRate30min), // // BasalRates (separately grouped) @@ -35,19 +36,16 @@ public enum PumpCapability { PumpCapability[] children; - PumpCapability() - { + PumpCapability() { } - PumpCapability(PumpCapability...children) - { + PumpCapability(PumpCapability... children) { this.children = children; } - public boolean hasCapability(PumpCapability capability) - { + public boolean hasCapability(PumpCapability capability) { // we can only check presense of simple capabilities if (capability.children != null) return false; @@ -55,19 +53,16 @@ public enum PumpCapability { if (this == capability) return true; - if (this.children!=null) - { + if (this.children != null) { for (PumpCapability child : children) { if (child == capability) return true; } return false; - } - else + } else return false; } - } diff --git a/core/src/main/java/info/nightscout/androidaps/services/AlarmSoundService.kt b/core/src/main/java/info/nightscout/androidaps/services/AlarmSoundService.kt index f84e6af6e2..6da80cf330 100644 --- a/core/src/main/java/info/nightscout/androidaps/services/AlarmSoundService.kt +++ b/core/src/main/java/info/nightscout/androidaps/services/AlarmSoundService.kt @@ -4,6 +4,7 @@ import android.content.Context import android.content.Intent import android.media.AudioManager import android.media.MediaPlayer +import android.os.Handler import android.os.IBinder import dagger.android.DaggerService import info.nightscout.androidaps.core.R @@ -11,16 +12,38 @@ import info.nightscout.androidaps.interfaces.NotificationHolderInterface import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.utils.resources.ResourceHelper +import info.nightscout.androidaps.utils.sharedPreferences.SP import javax.inject.Inject +import kotlin.math.ln +import kotlin.math.pow class AlarmSoundService : DaggerService() { @Inject lateinit var aapsLogger: AAPSLogger @Inject lateinit var resourceHelper: ResourceHelper @Inject lateinit var notificationHolder: NotificationHolderInterface + @Inject lateinit var sp: SP private var player: MediaPlayer? = null private var resourceId = R.raw.error + companion object { + private const val VOLUME_INCREASE_STEPS = 40 // Total number of steps to increase volume with + private const val VOLUME_INCREASE_INITIAL_SILENT_TIME_MILLIS = 3_000L // Number of milliseconds that the notification should initially be silent + private const val VOLUME_INCREASE_BASE_DELAY_MILLIS = 15_000 // Base delay between volume increments + private const val VOLUME_INCREASE_MIN_DELAY_MILLIS = 2_000L // Minimum delay between volume increments + + /* + * Delay until the next volumen increment will be the lowest value of VOLUME_INCREASE_MIN_DELAY_MILLIS and + * VOLUME_INCREASE_BASE_DELAY_MILLIS - (currentVolumeLevel - 1) ^ VOLUME_INCREASE_DELAY_DECREMENT_EXPONENT * 1000 + * + */ + private const val VOLUME_INCREASE_DELAY_DECREMENT_EXPONENT = 2.0 + + } + + private val increaseVolumeHandler = Handler() + private var currentVolumeLevel = 0 + override fun onBind(intent: Intent): IBinder? = null override fun onCreate() { @@ -41,10 +64,16 @@ class AlarmSoundService : DaggerService() { val afd = resourceHelper.openRawResourceFd(resourceId) ?: return START_STICKY player?.setDataSource(afd.fileDescriptor, afd.startOffset, afd.length) afd.close() - player?.isLooping = true // Set looping - val manager = getSystemService(Context.AUDIO_SERVICE) as AudioManager - if (!manager.isMusicActive) { - player?.setVolume(100f, 100f) + player?.isLooping = true + val audioManager = getAudioManager() + if (!audioManager.isMusicActive) { + if (sp.getBoolean(R.string.key_gradually_increase_notification_volume, false)) { + currentVolumeLevel = 0 + player?.setVolume(0f, 0f) + increaseVolumeHandler.postDelayed(volumeUpdater, VOLUME_INCREASE_INITIAL_SILENT_TIME_MILLIS) + } else { + player?.setVolume(1f, 1f) + } } player?.prepare() player?.start() @@ -55,8 +84,35 @@ class AlarmSoundService : DaggerService() { } override fun onDestroy() { + increaseVolumeHandler.removeCallbacks(volumeUpdater) player?.stop() player?.release() aapsLogger.debug(LTag.CORE, "onDestroy") } -} \ No newline at end of file + + private fun getAudioManager(): AudioManager { + return getSystemService(Context.AUDIO_SERVICE) as AudioManager + } + + // TODO replace with VolumeShaper when min API level >= 26 + private val volumeUpdater = object : Runnable { + override fun run() { + currentVolumeLevel++; + + val volumePercentage = 100.0.coerceAtMost(currentVolumeLevel / VOLUME_INCREASE_STEPS.toDouble() * 100) + val volume = (1 - (ln(1.0.coerceAtLeast(100.0 - volumePercentage)) / ln(100.0))).toFloat() + + aapsLogger.debug(LTag.CORE, "Setting notification volume to {} ({} %)", volume, volumePercentage) + + player?.setVolume(volume, volume) + + if (currentVolumeLevel < VOLUME_INCREASE_STEPS) { + // Increase volume faster as time goes by + val delay = VOLUME_INCREASE_MIN_DELAY_MILLIS.coerceAtLeast(VOLUME_INCREASE_BASE_DELAY_MILLIS - + ((currentVolumeLevel - 1).toDouble().pow(VOLUME_INCREASE_DELAY_DECREMENT_EXPONENT) * 1000).toLong()) + aapsLogger.debug(LTag.CORE, "Next notification volume increment in {}ms", delay) + increaseVolumeHandler.postDelayed(this, delay) + } + } + } +} diff --git a/core/src/main/java/info/nightscout/androidaps/utils/Translator.kt b/core/src/main/java/info/nightscout/androidaps/utils/Translator.kt index 501c2e7d1a..bb6901ea62 100644 --- a/core/src/main/java/info/nightscout/androidaps/utils/Translator.kt +++ b/core/src/main/java/info/nightscout/androidaps/utils/Translator.kt @@ -1,6 +1,7 @@ package info.nightscout.androidaps.utils import info.nightscout.androidaps.core.R +import info.nightscout.androidaps.db.CareportalEvent import info.nightscout.androidaps.utils.resources.ResourceHelper import javax.inject.Inject import javax.inject.Singleton @@ -15,30 +16,31 @@ class Translator @Inject internal constructor( fun translate(text: String): String = when (text) { - "BG Check" -> resourceHelper.gs(R.string.careportal_bgcheck) - "Snack Bolus" -> resourceHelper.gs(R.string.careportal_snackbolus) - "Meal Bolus" -> resourceHelper.gs(R.string.careportal_mealbolus) - "Correction Bolus" -> resourceHelper.gs(R.string.careportal_correctionbolus) - "Carb Correction" -> resourceHelper.gs(R.string.careportal_carbscorrection) - "Combo Bolus" -> resourceHelper.gs(R.string.careportal_combobolus) - "Announcement" -> resourceHelper.gs(R.string.careportal_announcement) - "Note" -> resourceHelper.gs(R.string.careportal_note) - "Question" -> resourceHelper.gs(R.string.careportal_question) - "Exercise" -> resourceHelper.gs(R.string.careportal_exercise) - "Site Change" -> resourceHelper.gs(R.string.careportal_pumpsitechange) - "Pump Battery Change" -> resourceHelper.gs(R.string.careportal_pumpbatterychange) - "Sensor Start" -> resourceHelper.gs(R.string.careportal_cgmsensorstart) - "Sensor Change" -> resourceHelper.gs(R.string.careportal_cgmsensorinsert) - "Insulin Change" -> resourceHelper.gs(R.string.careportal_insulincartridgechange) - "Temp Basal Start" -> resourceHelper.gs(R.string.careportal_tempbasalstart) - "Temp Basal End" -> resourceHelper.gs(R.string.careportal_tempbasalend) - "Profile Switch" -> resourceHelper.gs(R.string.careportal_profileswitch) - "Temporary Target" -> resourceHelper.gs(R.string.careportal_temporarytarget) - "Temporary Target Cancel" -> resourceHelper.gs(R.string.careportal_temporarytargetcancel) - "OpenAPS Offline" -> resourceHelper.gs(R.string.careportal_openapsoffline) - "Finger" -> resourceHelper.gs(R.string.glucosetype_finger) - "Sensor" -> resourceHelper.gs(R.string.glucosetype_sensor) - "Manual" -> resourceHelper.gs(R.string.manual) - else -> resourceHelper.gs(R.string.unknown) + CareportalEvent.BGCHECK -> resourceHelper.gs(R.string.careportal_bgcheck) + CareportalEvent.SNACKBOLUS -> resourceHelper.gs(R.string.careportal_snackbolus) + CareportalEvent.MEALBOLUS -> resourceHelper.gs(R.string.careportal_mealbolus) + CareportalEvent.CORRECTIONBOLUS -> resourceHelper.gs(R.string.careportal_correctionbolus) + CareportalEvent.CARBCORRECTION -> resourceHelper.gs(R.string.careportal_carbscorrection) + CareportalEvent.COMBOBOLUS -> resourceHelper.gs(R.string.careportal_combobolus) + CareportalEvent.ANNOUNCEMENT -> resourceHelper.gs(R.string.careportal_announcement) + CareportalEvent.NOTE -> resourceHelper.gs(R.string.careportal_note) + CareportalEvent.QUESTION -> resourceHelper.gs(R.string.careportal_question) + CareportalEvent.EXERCISE -> resourceHelper.gs(R.string.careportal_exercise) + CareportalEvent.SITECHANGE -> resourceHelper.gs(R.string.careportal_pumpsitechange) + CareportalEvent.PUMPBATTERYCHANGE -> resourceHelper.gs(R.string.careportal_pumpbatterychange) + CareportalEvent.SENSORSTART -> resourceHelper.gs(R.string.careportal_cgmsensorstart) + CareportalEvent.SENSORCHANGE -> resourceHelper.gs(R.string.careportal_cgmsensorinsert) + CareportalEvent.INSULINCHANGE -> resourceHelper.gs(R.string.careportal_insulincartridgechange) + CareportalEvent.TEMPBASALSTART -> resourceHelper.gs(R.string.careportal_tempbasalstart) + CareportalEvent.TEMPBASALEND -> resourceHelper.gs(R.string.careportal_tempbasalend) + CareportalEvent.PROFILESWITCH -> resourceHelper.gs(R.string.careportal_profileswitch) + CareportalEvent.TEMPORARYTARGET -> resourceHelper.gs(R.string.careportal_temporarytarget) + CareportalEvent.TEMPBASALCANCEL -> resourceHelper.gs(R.string.careportal_temporarytargetcancel) + CareportalEvent.OPENAPSOFFLINE -> resourceHelper.gs(R.string.careportal_openapsoffline) + CareportalEvent.MBG -> resourceHelper.gs(R.string.careportal_mbg) + CareportalEvent.FINGER -> resourceHelper.gs(R.string.glucosetype_finger) + CareportalEvent.SENSOR -> resourceHelper.gs(R.string.glucosetype_sensor) + CareportalEvent.MANUAL -> resourceHelper.gs(R.string.manual) + else -> resourceHelper.gs(R.string.unknown) } } \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/utils/textValidator/DefaultEditTextValidator.kt b/core/src/main/java/info/nightscout/androidaps/utils/textValidator/DefaultEditTextValidator.kt index 2956a8d2b8..94f3cfd3b6 100644 --- a/core/src/main/java/info/nightscout/androidaps/utils/textValidator/DefaultEditTextValidator.kt +++ b/core/src/main/java/info/nightscout/androidaps/utils/textValidator/DefaultEditTextValidator.kt @@ -1,7 +1,6 @@ package info.nightscout.androidaps.utils.textValidator import android.content.Context -import android.content.res.TypedArray import android.text.Editable import android.text.TextUtils import android.text.TextWatcher @@ -37,25 +36,20 @@ class DefaultEditTextValidator : EditTextValidator { resetValidators(context) } - constructor(editTextView: EditText, typedArray: TypedArray, context: Context) { - emptyAllowed = typedArray.getBoolean(R.styleable.FormEditText_emptyAllowed, false) - testType = typedArray.getInt(R.styleable.FormEditText_testType, EditTextValidator.TEST_NOCHECK) - testErrorString = typedArray.getString(R.styleable.FormEditText_testErrorString) - classType = typedArray.getString(R.styleable.FormEditText_classType) - customRegexp = typedArray.getString(R.styleable.FormEditText_customRegexp) - emptyErrorStringDef = typedArray.getString(R.styleable.FormEditText_emptyErrorString) - customFormat = typedArray.getString(R.styleable.FormEditText_customFormat) - if (testType == EditTextValidator.TEST_MIN_LENGTH) - minLength = typedArray.getInt(R.styleable.FormEditText_minLength, 0) - if (testType == EditTextValidator.TEST_NUMERIC_RANGE) { - minNumber = typedArray.getInt(R.styleable.FormEditText_minNumber, Int.MIN_VALUE) - maxNumber = typedArray.getInt(R.styleable.FormEditText_maxNumber, Int.MAX_VALUE) - } - if (testType == EditTextValidator.TEST_FLOAT_NUMERIC_RANGE) { - floatminNumber = typedArray.getFloat(R.styleable.FormEditText_floatminNumber, Float.MIN_VALUE) - floatmaxNumber = typedArray.getFloat(R.styleable.FormEditText_floatmaxNumber, Float.MAX_VALUE) - } - typedArray.recycle() + constructor(editTextView: EditText, parameters: Parameters, context: Context) { + emptyAllowed = parameters.emptyAllowed + testType = parameters.testType + testErrorString = parameters.testErrorString + classType = parameters.classType + customRegexp = parameters.customRegexp + emptyErrorStringDef = parameters.emptyErrorStringDef + customFormat = parameters.customFormat + minLength = parameters.minLength + minNumber = parameters.minNumber + maxNumber = parameters.maxNumber + floatminNumber = parameters.floatminNumber + floatmaxNumber = parameters.floatmaxNumber + setEditText(editTextView) resetValidators(context) } @@ -168,7 +162,7 @@ class DefaultEditTextValidator : EditTextValidator { } @Suppress("unused") - fun setClassType(classType: String?, testErrorString: String?, context: Context) : DefaultEditTextValidator{ + fun setClassType(classType: String?, testErrorString: String?, context: Context): DefaultEditTextValidator { testType = EditTextValidator.TEST_CUSTOM this.classType = classType this.testErrorString = testErrorString @@ -177,7 +171,7 @@ class DefaultEditTextValidator : EditTextValidator { } @Suppress("unused") - fun setCustomRegexp(customRegexp: String?, context: Context) : DefaultEditTextValidator { + fun setCustomRegexp(customRegexp: String?, context: Context): DefaultEditTextValidator { testType = EditTextValidator.TEST_REGEXP this.customRegexp = customRegexp resetValidators(context) @@ -185,13 +179,13 @@ class DefaultEditTextValidator : EditTextValidator { } @Suppress("unused") - fun setEmptyAllowed(emptyAllowed: Boolean, context: Context) : DefaultEditTextValidator { + fun setEmptyAllowed(emptyAllowed: Boolean, context: Context): DefaultEditTextValidator { this.emptyAllowed = emptyAllowed resetValidators(context) return this } - fun setEmptyErrorString(emptyErrorString: String?) : DefaultEditTextValidator { + fun setEmptyErrorString(emptyErrorString: String?): DefaultEditTextValidator { emptyErrorStringActual = if (!TextUtils.isEmpty(emptyErrorString)) { emptyErrorString } else { @@ -201,14 +195,14 @@ class DefaultEditTextValidator : EditTextValidator { } @Suppress("unused") - fun setTestErrorString(testErrorString: String?, context: Context) : DefaultEditTextValidator { + fun setTestErrorString(testErrorString: String?, context: Context): DefaultEditTextValidator { this.testErrorString = testErrorString resetValidators(context) return this } @Suppress("unused") - fun setTestType(testType: Int, context: Context) : DefaultEditTextValidator { + fun setTestType(testType: Int, context: Context): DefaultEditTextValidator { this.testType = testType resetValidators(context) return this @@ -248,4 +242,19 @@ class DefaultEditTextValidator : EditTextValidator { } catch (e: Throwable) { !TextUtils.isEmpty(editTextView.error) } + + class Parameters { + var testErrorString: String? = null + var emptyAllowed = false + var testType: Int = EditTextValidator.TEST_NOCHECK + var classType: String? = null + var customRegexp: String? = null + var customFormat: String? = null + var emptyErrorStringDef: String? = null + var minLength = 0 + var minNumber = 0 + var maxNumber = 0 + var floatminNumber = 0f + var floatmaxNumber = 0f + } } \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/utils/textValidator/ValidatingEditTextPreference.kt b/core/src/main/java/info/nightscout/androidaps/utils/textValidator/ValidatingEditTextPreference.kt index ae75641b4c..5bf97f6dee 100644 --- a/core/src/main/java/info/nightscout/androidaps/utils/textValidator/ValidatingEditTextPreference.kt +++ b/core/src/main/java/info/nightscout/androidaps/utils/textValidator/ValidatingEditTextPreference.kt @@ -1,22 +1,26 @@ package info.nightscout.androidaps.utils.textValidator -import android.annotation.SuppressLint import android.content.Context import android.util.AttributeSet import androidx.preference.EditTextPreference -import androidx.preference.EditTextPreference.OnBindEditTextListener import androidx.preference.PreferenceViewHolder import info.nightscout.androidaps.core.R class ValidatingEditTextPreference(ctx: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : EditTextPreference(ctx, attrs, defStyleAttr, defStyleRes) { + private lateinit var validatorParameters: DefaultEditTextValidator.Parameters + private var validator: DefaultEditTextValidator? = null + init { - val typedArray = context.obtainStyledAttributes(attrs, R.styleable.FormEditText, 0, 0) - val onBindEditTextListener = OnBindEditTextListener { editText -> - editTextValidator = DefaultEditTextValidator(editText, typedArray, context) + obtainValidatorParameters(attrs) + + setOnBindEditTextListener { editText -> + validator = DefaultEditTextValidator(editText, validatorParameters, context) + } + setOnPreferenceChangeListener { preference, newValue -> + validator?.testValidity(false) ?: true } - setOnBindEditTextListener(onBindEditTextListener) } constructor(ctx: Context, attrs: AttributeSet, defStyle: Int) @@ -25,11 +29,32 @@ class ValidatingEditTextPreference(ctx: Context, attrs: AttributeSet, defStyleAt constructor(ctx: Context, attrs: AttributeSet) : this(ctx, attrs, R.attr.editTextPreferenceStyle) - private lateinit var editTextValidator: EditTextValidator - override fun onBindViewHolder(holder: PreferenceViewHolder?) { super.onBindViewHolder(holder) holder?.isDividerAllowedAbove = false holder?.isDividerAllowedBelow = false } + + private fun obtainValidatorParameters(attrs: AttributeSet) { + val typedArray = context.obtainStyledAttributes(attrs, R.styleable.FormEditText, 0, 0) + validatorParameters = DefaultEditTextValidator.Parameters() + validatorParameters.emptyAllowed = typedArray.getBoolean(R.styleable.FormEditText_emptyAllowed, false) + validatorParameters.testType = typedArray.getInt(R.styleable.FormEditText_testType, EditTextValidator.TEST_NOCHECK) + validatorParameters.testErrorString = typedArray.getString(R.styleable.FormEditText_testErrorString) + validatorParameters.classType = typedArray.getString(R.styleable.FormEditText_classType) + validatorParameters.customRegexp = typedArray.getString(R.styleable.FormEditText_customRegexp) + validatorParameters.emptyErrorStringDef = typedArray.getString(R.styleable.FormEditText_emptyErrorString) + validatorParameters.customFormat = typedArray.getString(R.styleable.FormEditText_customFormat) + if (validatorParameters.testType == EditTextValidator.TEST_MIN_LENGTH) + validatorParameters.minLength = typedArray.getInt(R.styleable.FormEditText_minLength, 0) + if (validatorParameters.testType == EditTextValidator.TEST_NUMERIC_RANGE) { + validatorParameters.minNumber = typedArray.getInt(R.styleable.FormEditText_minNumber, Int.MIN_VALUE) + validatorParameters.maxNumber = typedArray.getInt(R.styleable.FormEditText_maxNumber, Int.MAX_VALUE) + } + if (validatorParameters.testType == EditTextValidator.TEST_FLOAT_NUMERIC_RANGE) { + validatorParameters.floatminNumber = typedArray.getFloat(R.styleable.FormEditText_floatminNumber, Float.MIN_VALUE) + validatorParameters.floatmaxNumber = typedArray.getFloat(R.styleable.FormEditText_floatmaxNumber, Float.MAX_VALUE) + } + typedArray.recycle() + } } diff --git a/core/src/main/res/values-af-rZA/strings.xml b/core/src/main/res/values-af-rZA/strings.xml index 547b8d8642..e60d671ab5 100644 --- a/core/src/main/res/values-af-rZA/strings.xml +++ b/core/src/main/res/values-af-rZA/strings.xml @@ -5,6 +5,7 @@ + diff --git a/core/src/main/res/values-bg-rBG/strings.xml b/core/src/main/res/values-bg-rBG/strings.xml index ab0a97b28a..7039b50890 100644 --- a/core/src/main/res/values-bg-rBG/strings.xml +++ b/core/src/main/res/values-bg-rBG/strings.xml @@ -101,6 +101,9 @@ седмици мин. д + + Грешна парола + Паролите не съвпадат Базалните стойности не са за кръгли часове: %1$s Базалната стойност е заместена от минимално поддържаната стойност %1$s diff --git a/core/src/main/res/values-cs-rCZ/strings.xml b/core/src/main/res/values-cs-rCZ/strings.xml index d8a92915a8..5c50a40e10 100644 --- a/core/src/main/res/values-cs-rCZ/strings.xml +++ b/core/src/main/res/values-cs-rCZ/strings.xml @@ -101,6 +101,9 @@ týdnů m d + + Chybné heslo + Hesla se neshodují Hodnoty bazálů nejsou zarovnané na celé hodiny: %1$s Hodnota bazálu nahrazena minimální možnou: %1$s @@ -128,6 +131,7 @@ %1$s: ∑: %2$.2f U Bol: %3$.2f U Baz: %4$.2f U(%5$.0f%%) Sach.: %6$.0f g]]> Kontrola glykémie + Ruční glykémie nebo kalibrace Oznámení Poznámka Otázka diff --git a/core/src/main/res/values-de-rDE/strings.xml b/core/src/main/res/values-de-rDE/strings.xml index 385e053603..ad417695c0 100644 --- a/core/src/main/res/values-de-rDE/strings.xml +++ b/core/src/main/res/values-de-rDE/strings.xml @@ -101,6 +101,9 @@ Wochen min d + + Falsches Passwort + Die Passwörter stimmen nicht überein. Basalraten beginnen nicht zur vollen Stunde: %1$s Basal-Wert wurde durch den kleinst möglichen Wert ersetzt: %1$s @@ -128,6 +131,7 @@ %1$s: ∑: %2$.2f IE Bol: %3$.2f U Bas: %4$.2f IE(%5$.0f%%) KH: %6$.0f g]]> BZ-Test + Manuelle BZ oder Kalibrierung Ankündigung Notiz Frage diff --git a/core/src/main/res/values-el-rGR/strings.xml b/core/src/main/res/values-el-rGR/strings.xml index 4a4b06493f..a39cd1c48c 100644 --- a/core/src/main/res/values-el-rGR/strings.xml +++ b/core/src/main/res/values-el-rGR/strings.xml @@ -5,6 +5,7 @@ + diff --git a/core/src/main/res/values-es-rES/strings.xml b/core/src/main/res/values-es-rES/strings.xml index 7969bb22d4..c151d08d3c 100644 --- a/core/src/main/res/values-es-rES/strings.xml +++ b/core/src/main/res/values-es-rES/strings.xml @@ -8,15 +8,22 @@ Perfil basal actualizado en bomba Datos inválidos Basal Temporal no emitida + Entregando %1$.2f U Esperando bomba Conexión por %1$d s + Entregando %1$.2f U Estableciendo comunicacion Conectando Conectado Desconectado Desconectando AndroidAPS iniciado + %1$.1f U + %1$.2f U + %1$+.2f U + %1$d g %1$.0f/%2$dU + %1$.2f U/h %1$.2f h %1$d min Bomba ocupada @@ -77,6 +84,8 @@ Ubicación no habilitada Para activar la visibilidad Bluetooth en nuevos dispositivos, la ubicación debe estar habilitada. AAPS no hace un seguimiento de su ubicación y se puede desactivar después de realizar la vinculación. + hace %1$d m + hace %1$.1f h h días horas @@ -92,6 +101,9 @@ semanas m d + + Contraseña incorrecta + Contraseñas no coinciden Valores basales no alineados a las horas: %1$s Valor basal reemplazado por el valor mínimo soportado: %1$s @@ -113,9 +125,13 @@ Perfil inválido: %1$s + %1$d min + %1$s: ∑: %2$.2fU Bol: %3$.2fU Bas: %4$.2fU(%5$.0f%%)]]> + %1$s: ∑: %2$.2fU Bol: %3$.2fU Bas: %4$.2fU(%5$.0f%%) Carbs: %6$.0fg]]> Medir glucosa + Calibración o BG Manual Aviso Nota Pregunta @@ -153,6 +169,7 @@ Esperando resultado SMB + %dg Carbohidratos adicionales necesarios dentro De %d minutos Estadísticas TDD acumulativa @@ -169,10 +186,31 @@ Basal diaria *2 Detección de tiempo + %1$dhoras %2$dmin + Operación no soportada por bomba y/o controlador. Operación no soportada todavía por la bomba. + Ok + Nunca conectados + En fase de inicio + Error con la comunicación + Tiempo de espera en la comunicación + Bomba no alcanzable + Configuración no válida + Activo + Suspendida + Basales + Ajustes + Notificaciones + Estadísticas + Desconocido/a + Todos + Bolos + Cebado + Alarmas + Glucosa diff --git a/core/src/main/res/values-fr-rFR/strings.xml b/core/src/main/res/values-fr-rFR/strings.xml index f835394731..e03ee413c5 100644 --- a/core/src/main/res/values-fr-rFR/strings.xml +++ b/core/src/main/res/values-fr-rFR/strings.xml @@ -101,6 +101,9 @@ semaines m j + + Mot de passe incorrect + Mots de passe différents Valeurs des débits de basal non alignées sur des heures: %1$s Valeur de basal remplacée par la valeur minimale autorisée : %1$s @@ -128,6 +131,7 @@ %1$s: ∑ : %2$.2f U Bol : %3$.2f U Bas : %4$.2f U (%5$.0f%%) Gluc : %6$.0f g]]> Contrôle Glycémie + Gly manuelle/Calib. Notification Remarque Question diff --git a/core/src/main/res/values-ga-rIE/strings.xml b/core/src/main/res/values-ga-rIE/strings.xml index 6cacb70673..8b1661cbb5 100644 --- a/core/src/main/res/values-ga-rIE/strings.xml +++ b/core/src/main/res/values-ga-rIE/strings.xml @@ -5,6 +5,7 @@ + diff --git a/core/src/main/res/values-hr-rHR/strings.xml b/core/src/main/res/values-hr-rHR/strings.xml index 6cacb70673..8b1661cbb5 100644 --- a/core/src/main/res/values-hr-rHR/strings.xml +++ b/core/src/main/res/values-hr-rHR/strings.xml @@ -5,6 +5,7 @@ + diff --git a/core/src/main/res/values-it-rIT/strings.xml b/core/src/main/res/values-it-rIT/strings.xml index 84791f1ea3..e96c363982 100644 --- a/core/src/main/res/values-it-rIT/strings.xml +++ b/core/src/main/res/values-it-rIT/strings.xml @@ -101,6 +101,9 @@ settimane m d + + Password errata + Le password non coincidono Valori basali non allineati alle ore: %1$s Valore basale sostituito dal minimo valore supportato: %1$s @@ -128,6 +131,7 @@ %1$s: ∑: %2$.2f U Bol: %3$.2f U Bas: %4$.2f U(%5$.0f%%) CHO: %6$.0f g]]> Controllo BG + BG manuale o Calibrazione Avviso Nota Domanda diff --git a/core/src/main/res/values-iw-rIL/strings.xml b/core/src/main/res/values-iw-rIL/strings.xml index 6cacb70673..8b1661cbb5 100644 --- a/core/src/main/res/values-iw-rIL/strings.xml +++ b/core/src/main/res/values-iw-rIL/strings.xml @@ -5,6 +5,7 @@ + diff --git a/core/src/main/res/values-ko-rKR/strings.xml b/core/src/main/res/values-ko-rKR/strings.xml index b8ceea7c1f..17c756e195 100644 --- a/core/src/main/res/values-ko-rKR/strings.xml +++ b/core/src/main/res/values-ko-rKR/strings.xml @@ -5,6 +5,7 @@ + diff --git a/core/src/main/res/values-lt-rLT/strings.xml b/core/src/main/res/values-lt-rLT/strings.xml index 74e46e0868..d10a20ae0e 100644 --- a/core/src/main/res/values-lt-rLT/strings.xml +++ b/core/src/main/res/values-lt-rLT/strings.xml @@ -8,15 +8,22 @@ Bazės profilis pompoje atnaujintas Neteisingai įvesti duomenys Laikinos bazės suleidimo klaida + Bus suleista %1$.2f vv Laukiama ryšio su pompa Jungiamasi %1$d s + Leidžiama %1$.2f vv Ryšio užmezgimas Jungiamasi Prisijungta Atsijungta Atsijungiama AndroidAPS paleista + %1$.1f vv + %1$.2f vv + %1$+.2f vv + %1$dg %1$.0f / %2$d vv + %1$.2f vv/val %1$.2f val. %1$d min. Pompa šiuo metu veikia @@ -77,6 +84,8 @@ Vietovės nustatymas neįjungtas Vietos nustatymo paslauga turi būti įjungta, kad Bluetooth aptikimas veiktų naujesniuose įrenginiuose. AAPS neseka Jūsų lokacijos, o vietos nustatymo paslauga gali būti išjungta po sėkmingo įrenginių suporavimo. + prieš %1$d min + Prieš %1$.1f val. val d. val. @@ -92,6 +101,9 @@ savaičių min. d + + Neteisingas slaptažodis + Slaptažodžiai nesutampa Bazės reikšmės nesuderintos su valandomis: %1$s Valandinė bazė pakeista mažiausia palaikoma verte: %1$s @@ -113,9 +125,13 @@ Netinkamas profilis: %1$s + %1$d min. + %1$s: ∑: %2$.2f vv Boluso: %3$.2f vv Bazės: %4$.2f vv(%5$.0f%%)]]> + %1$s: ∑: %2$.2f vv Boluso: %3$.2f vv Bazės: %4$.2f vv(%5$.0f%%) AV: %6$.0f g]]> KG testas + KG iš kraujo arba kalibracija Pranešimas Pastaba Klausimas @@ -153,6 +169,7 @@ Laukiama rezultato SMB + Būtina suvartoti %d g papildomų AV per %d min Statistika BPD viso diff --git a/core/src/main/res/values-nl-rNL/strings.xml b/core/src/main/res/values-nl-rNL/strings.xml index ea1668a7af..87eae6dfab 100644 --- a/core/src/main/res/values-nl-rNL/strings.xml +++ b/core/src/main/res/values-nl-rNL/strings.xml @@ -92,6 +92,7 @@ weken m d + Basaalstanden niet ingesteld in hele uren: %1$s Basale waarde vervangen door minimaal ondersteunde waarde; %1$s diff --git a/core/src/main/res/values-pl-rPL/strings.xml b/core/src/main/res/values-pl-rPL/strings.xml index 5d81b084e2..ba5e3b20e6 100644 --- a/core/src/main/res/values-pl-rPL/strings.xml +++ b/core/src/main/res/values-pl-rPL/strings.xml @@ -92,6 +92,7 @@ tygodni m d + Wartości bazy nie są ustawione w pełnych godzinach: %1$s Wartość bazy zastąpiona minimalną obsługiwaną wartością: %1$s diff --git a/core/src/main/res/values-pt-rBR/strings.xml b/core/src/main/res/values-pt-rBR/strings.xml index 19f6ad354a..d93703b523 100644 --- a/core/src/main/res/values-pt-rBR/strings.xml +++ b/core/src/main/res/values-pt-rBR/strings.xml @@ -90,6 +90,7 @@ dias semanas m + Valores das basais não definidos por horas: %1$s Valor da basal alterado para o valor mínimo suportado: %1$s diff --git a/core/src/main/res/values-pt-rPT/strings.xml b/core/src/main/res/values-pt-rPT/strings.xml index cd723f43ae..d126bb9804 100644 --- a/core/src/main/res/values-pt-rPT/strings.xml +++ b/core/src/main/res/values-pt-rPT/strings.xml @@ -8,15 +8,22 @@ Perfil Basal actualizado na bomba Entrada Inválida Erro na administração da Basal Temp + A ser administrado %1$.2f U À espera da bomba A ligar durante %1$d s + A administrar %1$.2f U Cumprimento A ligar Ligado Desligado A desligar AndroidAPS iniciado + %1$.1f U + %1$.2f U + %1$+.2f U + %1$d g %1$.0f / %2$d U + %1$.2f U/h %1$.2f h %1$d mins A bomba está ocupada @@ -77,6 +84,8 @@ Localização Não Está Activa Para a Pesquisa Bluetooth funcionar em dispositivos mais recentes, a localização deve ser activada. AAPS não acompanha a sua localização e pode ser desactivada após o emparelhamento bem-sucedido. + %1$d m atrás + %1$.1f h atrás h dias horas @@ -92,6 +101,9 @@ semanas m d + + Palavra-passe incorreta + Palavras-passe não correspondem Valores das basais não definidos por horas: %1$s Valor da basal alterado para o valor mínimo suportado: %1$s @@ -113,9 +125,13 @@ Perfil inválido: %1$s + %1$d min + %1$s: ∑: %2$.2f U Ból: %3$.2f U Bas: %4$.2f U(%5$.0f%%)]]> + %1$s: ∑: %2$.2f U Ból: %3$.2f U Bas: %4$.2f U(%5$.0f%%) Hidratos: %6$.0f g]]> Verificar Glic + Glicemia Manual or Calibração Anúncio Nota Questão @@ -153,6 +169,7 @@ À espera de resultado SMB + %d g Hidratos Adicionais Necessários Dentro de %d Minutos Estatísticas Dose diária acumulativa diff --git a/core/src/main/res/values-ro-rRO/strings.xml b/core/src/main/res/values-ro-rRO/strings.xml index 97227a6235..be8f993d94 100644 --- a/core/src/main/res/values-ro-rRO/strings.xml +++ b/core/src/main/res/values-ro-rRO/strings.xml @@ -92,6 +92,7 @@ săptămâni min z + Valori bazale nesincronizate cu ora: %1$s Valoarea bazalei a fost înlocuită cu valoarea minimă posibilă: %1$s diff --git a/core/src/main/res/values-ru-rRU/strings.xml b/core/src/main/res/values-ru-rRU/strings.xml index 54791a31c7..c33374d2ad 100644 --- a/core/src/main/res/values-ru-rRU/strings.xml +++ b/core/src/main/res/values-ru-rRU/strings.xml @@ -101,6 +101,9 @@ нед мин дн + + Неверный пароль + Пароли не совпадают Базальные значения не выровнены по часам: %1$s Значение базала заменено минимальной поддерживаемой величиной: %1$s @@ -128,6 +131,7 @@ %1$s∑: %2$.2fед Бол: %3$.2fед Баз: %4$.2fед(%5$.0f%%) Угл: %6$.0fг]]> Проверка ГК + Ввести значение ГК или калибровку Оовещение Примечание Вопрос diff --git a/core/src/main/res/values-sk-rSK/strings.xml b/core/src/main/res/values-sk-rSK/strings.xml index 1aacfad6ec..715982233f 100644 --- a/core/src/main/res/values-sk-rSK/strings.xml +++ b/core/src/main/res/values-sk-rSK/strings.xml @@ -101,6 +101,9 @@ týždňov m d + + Nesprávne heslo + Heslá sa nezhodujú Bazálne hodnoty nie sú zarovnané na celé hodiny: %1$s Hodnota bazálu nahradená minimálnou možnou: %1$s @@ -128,6 +131,7 @@ %1$s: ∑: %2$.2f JI Bol: %3$.2f JI Baz: %4$.2f JI(%5$.0f%%) Sach.: %6$.0f g]]> Kontrola glykémie + Ručné meranie, alebo kalibrácia Oznámenie Poznámka Otázka diff --git a/core/src/main/res/values-sl-rSI/strings.xml b/core/src/main/res/values-sl-rSI/strings.xml index 6cacb70673..8b1661cbb5 100644 --- a/core/src/main/res/values-sl-rSI/strings.xml +++ b/core/src/main/res/values-sl-rSI/strings.xml @@ -5,6 +5,7 @@ + diff --git a/core/src/main/res/values-sv-rSE/strings.xml b/core/src/main/res/values-sv-rSE/strings.xml index ae274cd2fd..45877484d3 100644 --- a/core/src/main/res/values-sv-rSE/strings.xml +++ b/core/src/main/res/values-sv-rSE/strings.xml @@ -8,15 +8,22 @@ Basalprofilen uppdaterad i pumpen Fel på inmatning Fel vid justering av temp basal + Kommer att leverera %1$.2f enheter Väntar på pump Ansluter (%1$d s) + Levererar %1$.2f enheter Anslutningen verifieras Ansluter Ansluten Frånkopplad Kopplar från AndroidAPS startad + %1$.1f U + %1$.2f U + %1$+.2f U + %1$dg %1$.0f / %2$d U + %1$.2f U/h %1$.2f h %1$d min Pump upptagen @@ -77,6 +84,8 @@ Platsdata är inte aktiverat För att Bluetooth ska fungera med nyare enheter, måste platsdata vara aktiverat. AAPS sparar inte din plats och det kan stängas av efter att enheten har parkopplats. + %1$dm sedan + %1$.1f tim sedan h dagar timmar @@ -92,6 +101,9 @@ veckor m d + + Fel lösenord + Lösenorden stämmer inte överens Profilens basaler är inte satta på hel timme: %1$s Basalvärdet ersatt med det lägsta tillåtna: %1$s @@ -113,9 +125,13 @@ Ogiltig profil: %1$s + %1$d min + %1$s: ∑: %2$.2fU Bol: %3$.2fU Bas: %4$.2fU(%5$.0f%%)]]> + %1$s: ∑: %2$.2fU Bol: %3$.2fU Bas: %4$.2fU(%5$.0f%%) KH: %6$.0fg]]> BG-kontroll + Manuellt BG eller kalibrering Meddelande Anteckning Fråga @@ -153,6 +169,7 @@ Väntar på resultat SMB + %dg KH behövs inom %d minuter Statistik Kumulativ TDD diff --git a/core/src/main/res/values-tr-rTR/strings.xml b/core/src/main/res/values-tr-rTR/strings.xml index 6cacb70673..8b1661cbb5 100644 --- a/core/src/main/res/values-tr-rTR/strings.xml +++ b/core/src/main/res/values-tr-rTR/strings.xml @@ -5,6 +5,7 @@ + diff --git a/core/src/main/res/values-zh-rCN/strings.xml b/core/src/main/res/values-zh-rCN/strings.xml index 3a1944bc64..38424a2b46 100644 --- a/core/src/main/res/values-zh-rCN/strings.xml +++ b/core/src/main/res/values-zh-rCN/strings.xml @@ -5,6 +5,7 @@ + diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index 47623f3feb..2836b47a52 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -1,5 +1,6 @@ + enable_fabric language units @@ -22,7 +23,9 @@ ns_uploadlocalprofile bt_watchdog bt_watchdog_last - Pairing + pump_unreachable_threshold + missed_bg_readings_threshold + gradually_increase_notification_volume Error @@ -88,6 +91,7 @@ Bluetooth BT Watchdog Switches off the phone\'s bluetooth for one second if no connection to the pump is possible. This may help on some phones where the bluetooth stack freezes. + Pairing Limiting max basal rate to %1$.2f U/h because of %2$s @@ -167,6 +171,7 @@ BG Check + Manual BG or Calibration Announcement Note Question @@ -280,5 +285,4 @@ - \ No newline at end of file diff --git a/crowdin.yml b/crowdin.yml index 6069f66394..d12e37292f 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -19,5 +19,7 @@ files: translation: /dana/src/main/res/values-%android_code%/strings.xml - source: /medtronic/src/main/res/values/strings.xml translation: /medtronic/src/main/res/values-%android_code%/strings.xml + - source: /omnipod/src/main/res/values/strings.xml + translation: /omnipod/src/main/res/values-%android_code%/strings.xml - source: /rileylink/src/main/res/values/strings.xml translation: /rileylink/src/main/res/values-%android_code%/strings.xml diff --git a/dana/src/main/java/info/nightscout/androidaps/dana/DanaFragment.kt b/dana/src/main/java/info/nightscout/androidaps/dana/DanaFragment.kt index 4585b80aa7..ba0c110823 100644 --- a/dana/src/main/java/info/nightscout/androidaps/dana/DanaFragment.kt +++ b/dana/src/main/java/info/nightscout/androidaps/dana/DanaFragment.kt @@ -27,6 +27,7 @@ import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.WarnColors 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.sharedPreferences.SP import io.reactivex.android.schedulers.AndroidSchedulers @@ -35,6 +36,7 @@ import kotlinx.android.synthetic.main.danar_fragment.* import javax.inject.Inject class DanaFragment : DaggerFragment() { + @Inject lateinit var rxBus: RxBusWrapper @Inject lateinit var aapsLogger: AAPSLogger @Inject lateinit var fabricPrivacy: FabricPrivacy @@ -95,6 +97,7 @@ class DanaFragment : DaggerFragment() { danar_btconnection.setOnLongClickListener { activity?.let { OKDialog.showConfirmation(it, resourceHelper.gs(R.string.resetpairing), Runnable { + aapsLogger.error("USER ENTRY: Clearing pairing keys !!!") (activePlugin.activePump as DanaPumpInterface).clearPairing() }) } @@ -212,9 +215,6 @@ class DanaFragment : DaggerFragment() { } //hide user options button if not an RS pump or old firmware // also excludes pump with model 03 because of untested error - val isKorean = activePlugin.activePump.pumpDescription.pumpType == PumpType.DanaRKorean - if (isKorean || pump.hwModel == 0 || pump.hwModel == 3) { - danar_user_options?.visibility = View.GONE - } + danar_user_options?.visibility = (pump.hwModel != 1 && pump.protocol != 0x00).toVisibility() } } diff --git a/dana/src/main/java/info/nightscout/androidaps/dana/DanaPump.kt b/dana/src/main/java/info/nightscout/androidaps/dana/DanaPump.kt index 175daea266..d687d27936 100644 --- a/dana/src/main/java/info/nightscout/androidaps/dana/DanaPump.kt +++ b/dana/src/main/java/info/nightscout/androidaps/dana/DanaPump.kt @@ -159,8 +159,8 @@ class DanaPump @Inject constructor( var v3RSPump = false; // User settings - var timeDisplayType = 0 - var buttonScrollOnOff = 0 + var timeDisplayType24 = false + var buttonScrollOnOff = false var beepAndAlarm = 0 var lcdOnTimeSec = 0 var backlightOnTimeSec = 0 diff --git a/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaUserOptionsActivity.kt b/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaUserOptionsActivity.kt index fafebe603d..03d51edf9b 100644 --- a/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaUserOptionsActivity.kt +++ b/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaUserOptionsActivity.kt @@ -28,6 +28,7 @@ import kotlin.math.max import kotlin.math.min class DanaUserOptionsActivity : NoSplashAppCompatActivity() { + @Inject lateinit var aapsLogger: AAPSLogger @Inject lateinit var rxBus: RxBusWrapper @Inject lateinit var fabricPrivacy: FabricPrivacy @@ -71,9 +72,9 @@ class DanaUserOptionsActivity : NoSplashAppCompatActivity() { aapsLogger.debug(LTag.PUMP, "UserOptionsLoaded:" + (System.currentTimeMillis() - danaPump.lastConnection) / 1000 + " s ago" - + "\ntimeDisplayType:" + danaPump.timeDisplayType + + "\ntimeDisplayType24:" + danaPump.timeDisplayType24 + "\nbuttonScroll:" + danaPump.buttonScrollOnOff - + "\ntimeDisplayType:" + danaPump.timeDisplayType + + "\nbeepAndAlarm:" + danaPump.beepAndAlarm + "\nlcdOnTimeSec:" + danaPump.lcdOnTimeSec + "\nbackLight:" + danaPump.backlightOnTimeSec + "\npumpUnits:" + danaPump.units @@ -84,33 +85,35 @@ class DanaUserOptionsActivity : NoSplashAppCompatActivity() { danar_shutdown.setParams(danaPump.shutdownHour.toDouble(), 0.0, 24.0, 1.0, DecimalFormat("1"), true, save_user_options) danar_lowreservoir.setParams(danaPump.lowReservoirRate.toDouble(), 10.0, 50.0, 10.0, DecimalFormat("10"), false, save_user_options) when (danaPump.beepAndAlarm) { - 0x01 -> danar_pumpalarm_sound.isChecked = true - 0x02 -> danar_pumpalarm_vibrate.isChecked = true - 0x11 -> danar_pumpalarm_both.isChecked = true + 0b01 -> danar_pumpalarm_sound.isChecked = true + 0b10 -> danar_pumpalarm_vibrate.isChecked = true + 0b11 -> danar_pumpalarm_both.isChecked = true - 0x101 -> { + 0b101 -> { danar_pumpalarm_sound.isChecked = true danar_beep.isChecked = true } - 0x110 -> { + 0b110 -> { danar_pumpalarm_vibrate.isChecked = true danar_beep.isChecked = true } - 0x111 -> { + 0b111 -> { danar_pumpalarm_both.isChecked = true danar_beep.isChecked = true } } - if (danaPump.lastSettingsRead == 0L) - aapsLogger.error(LTag.PUMP, "No settings loaded from pump!") else setData() + if (danaPump.lastSettingsRead == 0L && danaPump.hwModel < 0x05) // RS+ doesn't use lastSettingsRead + aapsLogger.error(LTag.PUMP, "No settings loaded from pump!") + else + setData() } fun setData() { // in DanaRS timeDisplay values are reversed - danar_timeformat.isChecked = !isRS() && danaPump.timeDisplayType != 0 || isRS() && danaPump.timeDisplayType == 0 - danar_buttonscroll.isChecked = danaPump.buttonScrollOnOff != 0 + danar_timeformat.isChecked = danaPump.timeDisplayType24 + danar_buttonscroll.isChecked = danaPump.buttonScrollOnOff danar_beep.isChecked = danaPump.beepAndAlarm > 4 danar_screentimeout.value = danaPump.lcdOnTimeSec.toDouble() danar_backlight.value = danaPump.backlightOnTimeSec.toDouble() @@ -123,12 +126,9 @@ class DanaUserOptionsActivity : NoSplashAppCompatActivity() { //exit if pump is not DanaRS, DanaR, or DanaR with upgraded firmware if (!isRS() && !isDanaR() && !isDanaRv2()) return - if (isRS()) // displayTime on RS is reversed - danaPump.timeDisplayType = if (danar_timeformat.isChecked) 0 else 1 - else - danaPump.timeDisplayType = if (danar_timeformat.isChecked) 1 else 0 + danaPump.timeDisplayType24 = danar_timeformat.isChecked - danaPump.buttonScrollOnOff = if (danar_buttonscroll.isChecked) 1 else 0 + danaPump.buttonScrollOnOff = danar_buttonscroll.isChecked danaPump.beepAndAlarm = when { danar_pumpalarm_sound.isChecked -> 1 danar_pumpalarm_vibrate.isChecked -> 2 diff --git a/dana/src/main/res/values-bg-rBG/strings.xml b/dana/src/main/res/values-bg-rBG/strings.xml index 72d2e51a94..89429ecb0f 100644 --- a/dana/src/main/res/values-bg-rBG/strings.xml +++ b/dana/src/main/res/values-bg-rBG/strings.xml @@ -54,7 +54,6 @@ Обновява базални стойности Настройва временен базал Изчаква синхронизация на времето (%1$d сек) - Грешна парола Грешна парола за помпата! Аларми Базален по часове diff --git a/dana/src/main/res/values-cs-rCZ/strings.xml b/dana/src/main/res/values-cs-rCZ/strings.xml index 695e20aefe..7b59410fa4 100644 --- a/dana/src/main/res/values-cs-rCZ/strings.xml +++ b/dana/src/main/res/values-cs-rCZ/strings.xml @@ -54,7 +54,6 @@ Aktualizuji bazály Nastavuji dočasný bazál Čekání na synchronizaci času (%1$d s) - Chybné heslo Špatné heslo k pumpě! Alarmy Hodinové bazály diff --git a/dana/src/main/res/values-de-rDE/strings.xml b/dana/src/main/res/values-de-rDE/strings.xml index 56f9391d6e..0f2cef2b26 100644 --- a/dana/src/main/res/values-de-rDE/strings.xml +++ b/dana/src/main/res/values-de-rDE/strings.xml @@ -54,7 +54,6 @@ Basal-Profil wird aktualisiert TBR wird gesetzt Warte auf Zeitsynchronisierung (%1$d Sek.) - Falsches Passwort Falsches Pumpen-Passwort! Alarme Basal-Stunden diff --git a/dana/src/main/res/values-es-rES/strings.xml b/dana/src/main/res/values-es-rES/strings.xml index f2c9d14b44..5bcb1a9d39 100644 --- a/dana/src/main/res/values-es-rES/strings.xml +++ b/dana/src/main/res/values-es-rES/strings.xml @@ -54,7 +54,6 @@ Actualizando dosis basales Ajustando basal temporal Esperando para sincronización (%1$d sec) - Contraseña incorrecta ¡Contraseña de la bomba incorrecta! Alarmas Basal Horas diff --git a/dana/src/main/res/values-fr-rFR/strings.xml b/dana/src/main/res/values-fr-rFR/strings.xml index 21eec0d92f..99f12323a4 100644 --- a/dana/src/main/res/values-fr-rFR/strings.xml +++ b/dana/src/main/res/values-fr-rFR/strings.xml @@ -54,7 +54,6 @@ Mise à jour des débits basal Définir basal temp Attente de synchronisation de l\'heure (%1$d sec) - Mot de passe incorrect Mot de passe pompe incorrect ! Alarmes Heures Basal diff --git a/dana/src/main/res/values-it-rIT/strings.xml b/dana/src/main/res/values-it-rIT/strings.xml index 11329423d5..a8c579f6a9 100644 --- a/dana/src/main/res/values-it-rIT/strings.xml +++ b/dana/src/main/res/values-it-rIT/strings.xml @@ -54,7 +54,6 @@ Aggiornamento velocità basali Impostazione basale temporanea In attesa della sincronizzazione dell\'ora (%1$d sec) - Password errata Password micro errata! Allarmi Ore basali diff --git a/dana/src/main/res/values-lt-rLT/strings.xml b/dana/src/main/res/values-lt-rLT/strings.xml index bca4fcbf52..ba204dd39e 100644 --- a/dana/src/main/res/values-lt-rLT/strings.xml +++ b/dana/src/main/res/values-lt-rLT/strings.xml @@ -54,7 +54,6 @@ Bazė naujinama Laikinos bazės nustatymas Laukiama laiko sinchronizavimo (%1$d sek.) - Neteisingas slaptažodis Neteisingas pompos slaptažodis! Aliarmai Valandinė bazė diff --git a/dana/src/main/res/values-nl-rNL/strings.xml b/dana/src/main/res/values-nl-rNL/strings.xml index ac4438bf96..9e4b8f12e1 100644 --- a/dana/src/main/res/values-nl-rNL/strings.xml +++ b/dana/src/main/res/values-nl-rNL/strings.xml @@ -54,7 +54,6 @@ Bijwerken basaal profiel Instellen tijdelijk basaal Wachten op tijdsynchronisatie (%1$d sec) - Verkeerd wachtwoord Verkeerd pomp wachtwoord! Alarmen Basale uren diff --git a/dana/src/main/res/values-pl-rPL/strings.xml b/dana/src/main/res/values-pl-rPL/strings.xml index 9f84c6cd35..4b268ae95d 100644 --- a/dana/src/main/res/values-pl-rPL/strings.xml +++ b/dana/src/main/res/values-pl-rPL/strings.xml @@ -54,7 +54,6 @@ Uaktualnianie dawek bazowych Ustawianie bazy tymczasowej Oczekiwanie na synchronizację czasu (%1$d sec) - Złe hasło Błędne hasło pompy! Alarmy Godziny Bazy diff --git a/dana/src/main/res/values-pt-rBR/strings.xml b/dana/src/main/res/values-pt-rBR/strings.xml index 756ea27a45..204d3ba1a7 100644 --- a/dana/src/main/res/values-pt-rBR/strings.xml +++ b/dana/src/main/res/values-pt-rBR/strings.xml @@ -46,7 +46,6 @@ Atualizar valores das basais Definindo basal temp À espera da sincronização da hora (%1$d sec) - Senha incorrecta Senha da bomba incorrecta! Alarmes Horas de Basal diff --git a/dana/src/main/res/values-pt-rPT/strings.xml b/dana/src/main/res/values-pt-rPT/strings.xml index 2a9b392910..58af75e295 100644 --- a/dana/src/main/res/values-pt-rPT/strings.xml +++ b/dana/src/main/res/values-pt-rPT/strings.xml @@ -54,7 +54,6 @@ A actualizar taxas das basais Definindo basal temp À espera da sincronização da hora (%1$d sec) - Senha incorrecta Senha da bomba incorrecta! Alarmes Horas de Basal diff --git a/dana/src/main/res/values-ro-rRO/strings.xml b/dana/src/main/res/values-ro-rRO/strings.xml index c75c37a78f..589940f04e 100644 --- a/dana/src/main/res/values-ro-rRO/strings.xml +++ b/dana/src/main/res/values-ro-rRO/strings.xml @@ -54,7 +54,6 @@ Se actualizează ratele bazale Se setează bazala temporară Se așteaptă o sincronizare a timpului (%1$d s) - Parolă greșită Parola pompei greșită! Alarme Ore bazale diff --git a/dana/src/main/res/values-ru-rRU/strings.xml b/dana/src/main/res/values-ru-rRU/strings.xml index b62cc03edd..df0577758a 100644 --- a/dana/src/main/res/values-ru-rRU/strings.xml +++ b/dana/src/main/res/values-ru-rRU/strings.xml @@ -54,7 +54,6 @@ обновление значений базала установка врем базала Ожидание синхронизации времени (%1$d сек) - неверный пароль неверный пароль помпы оповещения об опасности почасовые базалы diff --git a/dana/src/main/res/values-sk-rSK/strings.xml b/dana/src/main/res/values-sk-rSK/strings.xml index 9e6e2cfd8e..d4464b9fdf 100644 --- a/dana/src/main/res/values-sk-rSK/strings.xml +++ b/dana/src/main/res/values-sk-rSK/strings.xml @@ -54,7 +54,6 @@ Aktualizujem bazály Nastavujem dočasný bazál Čakanie na synchronizáciu času (%1$d s) - Nesprávne heslo Nesprávne heslo do pumpy! Alarmy Hodinové bazály diff --git a/dana/src/main/res/values-sv-rSE/strings.xml b/dana/src/main/res/values-sv-rSE/strings.xml index 94bc25e158..e360cafe02 100644 --- a/dana/src/main/res/values-sv-rSE/strings.xml +++ b/dana/src/main/res/values-sv-rSE/strings.xml @@ -54,7 +54,6 @@ Uppdaterar basaldoser Ställer in temp basal Väntar på tidssynkronisering (%1$d sek) - Fel lösenord Fel lösenord för pump Larm Basaltimmar diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetUserOptions.kt b/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetUserOptions.kt index 68d6ef73d9..142e3d85d0 100644 --- a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetUserOptions.kt +++ b/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetUserOptions.kt @@ -13,8 +13,8 @@ class MsgSetUserOptions( // No options set -> Exiting aapsLogger.debug(LTag.PUMPCOMM, "NO USER OPTIONS LOADED EXITING!") } else { - danaPump.userOptionsFrompump!![0] = (if (danaPump.timeDisplayType == 1) 0 else 1).toByte() - danaPump.userOptionsFrompump!![1] = danaPump.buttonScrollOnOff.toByte() + danaPump.userOptionsFrompump!![0] = if( danaPump.timeDisplayType24) 0.toByte() else 1.toByte() + danaPump.userOptionsFrompump!![1] = if (danaPump.buttonScrollOnOff) 1.toByte() else 0.toByte() danaPump.userOptionsFrompump!![2] = danaPump.beepAndAlarm.toByte() danaPump.userOptionsFrompump!![3] = danaPump.lcdOnTimeSec.toByte() danaPump.userOptionsFrompump!![4] = danaPump.backlightOnTimeSec.toByte() diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingUserOptions.kt b/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingUserOptions.kt index 9f3350a579..2d7d703994 100644 --- a/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingUserOptions.kt +++ b/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSettingUserOptions.kt @@ -20,22 +20,22 @@ class MsgSettingUserOptions( for (pos in bytes.indices) { aapsLogger.debug(LTag.PUMPCOMM, "[" + pos + "]" + bytes[pos]) } - danaPump.timeDisplayType = if (bytes[0] == 1.toByte()) 0 else 1 // 1 -> 24h 0 -> 12h - danaPump.buttonScrollOnOff = if (bytes[1] == 1.toByte()) 1 else 0 // 1 -> ON, 0-> OFF + danaPump.timeDisplayType24 = bytes[0].toInt() == 0 // 0 -> 24h 1 -> 12h + danaPump.buttonScrollOnOff = bytes[1] == 1.toByte() // 1 -> ON, 0-> OFF danaPump.beepAndAlarm = bytes[2].toInt() // 1 -> Sound on alarm 2-> Vibrate on alarm 3-> Both on alarm 5-> Sound + beep 6-> vibrate + beep 7-> both + beep Beep adds 4 - danaPump.lcdOnTimeSec = bytes[3].toInt() and 255 - danaPump.backlightOnTimeSec = bytes[4].toInt() and 255 + danaPump.lcdOnTimeSec = bytes[3].toInt() + danaPump.backlightOnTimeSec = bytes[4].toInt() danaPump.selectedLanguage = bytes[5].toInt() // on DanaRv2 is that needed ? danaPump.units = bytes[8].toInt() danaPump.shutdownHour = bytes[9].toInt() - danaPump.lowReservoirRate = bytes[32].toInt() and 255 + danaPump.lowReservoirRate = bytes[32].toInt() /* int selectableLanguage1 = bytes[10]; int selectableLanguage2 = bytes[11]; int selectableLanguage3 = bytes[12]; int selectableLanguage4 = bytes[13]; int selectableLanguage5 = bytes[14]; */ - aapsLogger.debug(LTag.PUMPCOMM, "timeDisplayType: " + danaPump.timeDisplayType) + aapsLogger.debug(LTag.PUMPCOMM, "timeDisplayType24: " + danaPump.timeDisplayType24) aapsLogger.debug(LTag.PUMPCOMM, "Button scroll: " + danaPump.buttonScrollOnOff) aapsLogger.debug(LTag.PUMPCOMM, "BeepAndAlarm: " + danaPump.beepAndAlarm) aapsLogger.debug(LTag.PUMPCOMM, "screen timeout: " + danaPump.lcdOnTimeSec) diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Get_User_Option.kt b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Get_User_Option.kt index c9fe481da8..f0232854f7 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Get_User_Option.kt +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Get_User_Option.kt @@ -20,10 +20,10 @@ class DanaRS_Packet_Option_Get_User_Option( override fun handleMessage(data: ByteArray) { var dataIndex = DATA_START var dataSize = 1 - danaPump.timeDisplayType = byteArrayToInt(getBytes(data, dataIndex, dataSize)) + danaPump.timeDisplayType24 = byteArrayToInt(getBytes(data, dataIndex, dataSize)) == 0 dataIndex += dataSize dataSize = 1 - danaPump.buttonScrollOnOff = byteArrayToInt(getBytes(data, dataIndex, dataSize)) + danaPump.buttonScrollOnOff = byteArrayToInt(getBytes(data, dataIndex, dataSize)) == 1 dataIndex += dataSize dataSize = 1 danaPump.beepAndAlarm = byteArrayToInt(getBytes(data, dataIndex, dataSize)) @@ -68,7 +68,7 @@ class DanaRS_Packet_Option_Get_User_Option( val selectableLanguage5 = byteArrayToInt(getBytes(data, dataIndex, dataSize)) // Pump's screen on time can't be less than 5 failed = if (danaPump.lcdOnTimeSec < 5) true else false - aapsLogger.debug(LTag.PUMPCOMM, "timeDisplayType: " + danaPump.timeDisplayType) + aapsLogger.debug(LTag.PUMPCOMM, "timeDisplayType24: " + danaPump.timeDisplayType24) aapsLogger.debug(LTag.PUMPCOMM, "buttonScrollOnOff: " + danaPump.buttonScrollOnOff) aapsLogger.debug(LTag.PUMPCOMM, "beepAndAlarm: " + danaPump.beepAndAlarm) aapsLogger.debug(LTag.PUMPCOMM, "lcdOnTimeSec: " + danaPump.lcdOnTimeSec) diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Set_User_Option.kt b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Set_User_Option.kt index c6572d6f60..78db5a28c2 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Set_User_Option.kt +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_Option_Set_User_Option.kt @@ -20,16 +20,16 @@ class DanaRS_Packet_Option_Set_User_Option( override fun getRequestParams(): ByteArray { aapsLogger.debug(LTag.PUMPCOMM, "UserOptions:" + (System.currentTimeMillis() - danaPump.lastConnection) / 1000 + " s ago" - + "\ntimeDisplayType:" + danaPump.timeDisplayType + + "\ntimeDisplayType24:" + danaPump.timeDisplayType24 + "\nbuttonScroll:" + danaPump.buttonScrollOnOff - + "\ntimeDisplayType:" + danaPump.timeDisplayType + + "\nbeepAndAlarm:" + danaPump.beepAndAlarm + "\nlcdOnTimeSec:" + danaPump.lcdOnTimeSec + "\nbacklight:" + danaPump.backlightOnTimeSec + "\ndanaRPumpUnits:" + danaPump.units + "\nlowReservoir:" + danaPump.lowReservoirRate) val request = ByteArray(13) - request[0] = (danaPump.timeDisplayType and 0xff).toByte() - request[1] = (danaPump.buttonScrollOnOff and 0xff).toByte() + request[0] = if (danaPump.timeDisplayType24) 0.toByte() else 1.toByte() + request[1] = if (danaPump.buttonScrollOnOff) 1.toByte() else 0.toByte() request[2] = (danaPump.beepAndAlarm and 0xff).toByte() request[3] = (danaPump.lcdOnTimeSec and 0xff).toByte() request[4] = (danaPump.backlightOnTimeSec and 0xff).toByte() diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/services/BLEComm.kt b/danars/src/main/java/info/nightscout/androidaps/danars/services/BLEComm.kt index cc24cf5c22..be6a4fde0a 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/services/BLEComm.kt +++ b/danars/src/main/java/info/nightscout/androidaps/danars/services/BLEComm.kt @@ -51,6 +51,7 @@ class BLEComm @Inject internal constructor( ) { companion object { + private const val WRITE_DELAY_MILLIS: Long = 50 private const val UART_READ_UUID = "0000fff1-0000-1000-8000-00805f9b34fb" private const val UART_WRITE_UUID = "0000fff2-0000-1000-8000-00805f9b34fb" @@ -375,22 +376,22 @@ class BLEComm @Inject internal constructor( if (decryptedBuffer[0] == BleEncryption.DANAR_PACKET__TYPE_ENCRYPTION_RESPONSE.toByte()) { when (decryptedBuffer[1]) { // 1st packet exchange - BleEncryption.DANAR_PACKET__OPCODE_ENCRYPTION__PUMP_CHECK.toByte() -> + BleEncryption.DANAR_PACKET__OPCODE_ENCRYPTION__PUMP_CHECK.toByte() -> processConnectResponse(decryptedBuffer) - BleEncryption.DANAR_PACKET__OPCODE_ENCRYPTION__TIME_INFORMATION.toByte() -> + BleEncryption.DANAR_PACKET__OPCODE_ENCRYPTION__TIME_INFORMATION.toByte() -> processEncryptionResponse(decryptedBuffer) - BleEncryption.DANAR_PACKET__OPCODE_ENCRYPTION__CHECK_PASSKEY.toByte() -> + BleEncryption.DANAR_PACKET__OPCODE_ENCRYPTION__CHECK_PASSKEY.toByte() -> processPasskeyCheck(decryptedBuffer) - BleEncryption.DANAR_PACKET__OPCODE_ENCRYPTION__PASSKEY_REQUEST.toByte() -> + BleEncryption.DANAR_PACKET__OPCODE_ENCRYPTION__PASSKEY_REQUEST.toByte() -> processPairingRequest(decryptedBuffer) - BleEncryption.DANAR_PACKET__OPCODE_ENCRYPTION__PASSKEY_RETURN.toByte() -> + BleEncryption.DANAR_PACKET__OPCODE_ENCRYPTION__PASSKEY_RETURN.toByte() -> processPairingRequest2(decryptedBuffer) - BleEncryption.DANAR_PACKET__OPCODE_ENCRYPTION__GET_PUMP_CHECK.toByte() -> { + BleEncryption.DANAR_PACKET__OPCODE_ENCRYPTION__GET_PUMP_CHECK.toByte() -> { // not easy mode, request time info if (decryptedBuffer[2] == 0x05.toByte()) sendTimeInfo() // easy mode @@ -453,32 +454,19 @@ class BLEComm @Inject internal constructor( // v3 2nd layer encryption v3Encryption = true danaPump.v3RSPump = true - val model = decryptedBuffer[5] - // val protocol = decryptedBuffer[7] - if (model == 0x05.toByte()) { + danaPump.hwModel = decryptedBuffer[5].toInt() + danaPump.protocol = decryptedBuffer[7].toInt() + // grab randomSyncKey + sp.putString(resourceHelper.gs(R.string.key_danars_v3_randomsynckey) + danaRSPlugin.mDeviceName, String.format("%02x", decryptedBuffer[decryptedBuffer.size - 1])) + + if (danaPump.hwModel == 0x05) { aapsLogger.debug(LTag.PUMPBTCOMM, "<<<<< " + "ENCRYPTION__PUMP_CHECK V3 (OK)" + " " + DanaRS_Packet.toHexString(decryptedBuffer)) // Dana RS Pump - val randomPairingKey = sp.getString(resourceHelper.gs(R.string.key_danars_v3_randompairingkey) + danaRSPlugin.mDeviceName, "") - val pairingKey = sp.getString(resourceHelper.gs(R.string.key_danars_v3_pairingkey) + danaRSPlugin.mDeviceName, "") - if (randomPairingKey.isNotEmpty() && pairingKey.isNotEmpty()) { - val randomSyncKey = String.format("%02x", decryptedBuffer[decryptedBuffer.size - 1]) - sp.putString(resourceHelper.gs(R.string.key_danars_v3_randomsynckey) + danaRSPlugin.mDeviceName, randomSyncKey) - val tPairingKey = Base64.decode(pairingKey, Base64.DEFAULT) - val tRandomPairingKey = Base64.decode(randomPairingKey, Base64.DEFAULT) - var tRandomSyncKey: Byte = 0 - if (randomSyncKey.isNotEmpty()) { - tRandomSyncKey = randomSyncKey.toInt(16).toByte() - } - bleEncryption.setPairingKeys(tPairingKey, tRandomPairingKey, tRandomSyncKey) - sendV3PairingInformation(0) - } else { - sendV3PairingInformation(1) - } - } else if (model == 0x06.toByte()) { + sendV3PairingInformation() + } else if (danaPump.hwModel == 0x06) { aapsLogger.debug(LTag.PUMPBTCOMM, "<<<<< " + "ENCRYPTION__PUMP_CHECK V3 EASY (OK)" + " " + DanaRS_Packet.toHexString(decryptedBuffer)) // Dana RS Easy - val bytes: ByteArray = bleEncryption.getEncryptedPacket(BleEncryption.DANAR_PACKET__OPCODE_ENCRYPTION__GET_EASYMENU_CHECK, null, null) - writeCharacteristicNoResponse(uartWriteBTGattChar, bytes) + sendEasyMenuCheck() } // response PUMP : error status } else if (decryptedBuffer.size == 6 && decryptedBuffer[2] == 'P'.toByte() && decryptedBuffer[3] == 'U'.toByte() && decryptedBuffer[4] == 'M'.toByte() && decryptedBuffer[5] == 'P'.toByte()) { @@ -523,6 +511,24 @@ class BLEComm @Inject internal constructor( // 2nd packet v3 // 0x00 Start encryption, 0x01 Request pairing + private fun sendV3PairingInformation() { + val randomPairingKey = sp.getString(resourceHelper.gs(R.string.key_danars_v3_randompairingkey) + danaRSPlugin.mDeviceName, "") + val pairingKey = sp.getString(resourceHelper.gs(R.string.key_danars_v3_pairingkey) + danaRSPlugin.mDeviceName, "") + if (randomPairingKey.isNotEmpty() && pairingKey.isNotEmpty()) { + val tPairingKey = Base64.decode(pairingKey, Base64.DEFAULT) + val tRandomPairingKey = Base64.decode(randomPairingKey, Base64.DEFAULT) + var tRandomSyncKey: Byte = 0 + val randomSyncKey = sp.getString(resourceHelper.gs(R.string.key_danars_v3_randomsynckey) + danaRSPlugin.mDeviceName, "") + if (randomSyncKey.isNotEmpty()) { + tRandomSyncKey = randomSyncKey.toInt(16).toByte() + } + bleEncryption.setPairingKeys(tPairingKey, tRandomPairingKey, tRandomSyncKey) + sendV3PairingInformation(0) + } else { + sendV3PairingInformation(1) + } + } + private fun sendV3PairingInformation(requestNewPairing: Int) { val params = byteArrayOf(requestNewPairing.toByte()) val bytes: ByteArray = bleEncryption.getEncryptedPacket(BleEncryption.DANAR_PACKET__OPCODE_ENCRYPTION__TIME_INFORMATION, params, null) @@ -635,7 +641,7 @@ class BLEComm @Inject internal constructor( isUnitUD = decryptedBuffer[3] == 0x01.toByte() // request time information - if (v3Encryption) sendV3PairingInformation(1) + if (v3Encryption) sendV3PairingInformation() else sendTimeInfo() } diff --git a/danars/src/main/jniLibs/arm64-v8a/libBleEncryption.so b/danars/src/main/jniLibs/arm64-v8a/libBleEncryption.so index 59e0c56433..c5fddf8925 100644 Binary files a/danars/src/main/jniLibs/arm64-v8a/libBleEncryption.so and b/danars/src/main/jniLibs/arm64-v8a/libBleEncryption.so differ diff --git a/danars/src/main/jniLibs/armeabi-v7a/libBleEncryption.so b/danars/src/main/jniLibs/armeabi-v7a/libBleEncryption.so index fabc03368a..47acae4c14 100644 Binary files a/danars/src/main/jniLibs/armeabi-v7a/libBleEncryption.so and b/danars/src/main/jniLibs/armeabi-v7a/libBleEncryption.so differ diff --git a/danars/src/main/jniLibs/x86/libBleEncryption.so b/danars/src/main/jniLibs/x86/libBleEncryption.so index fb51d4816f..0c860f07d9 100644 Binary files a/danars/src/main/jniLibs/x86/libBleEncryption.so and b/danars/src/main/jniLibs/x86/libBleEncryption.so differ diff --git a/danars/src/main/jniLibs/x86_64/libBleEncryption.so b/danars/src/main/jniLibs/x86_64/libBleEncryption.so index 777d55b7f6..48d5708f60 100644 Binary files a/danars/src/main/jniLibs/x86_64/libBleEncryption.so and b/danars/src/main/jniLibs/x86_64/libBleEncryption.so differ diff --git a/medtronic/src/main/res/values-es-rES/strings.xml b/medtronic/src/main/res/values-es-rES/strings.xml index f438320ae9..1dd41aea2f 100644 --- a/medtronic/src/main/res/values-es-rES/strings.xml +++ b/medtronic/src/main/res/values-es-rES/strings.xml @@ -25,6 +25,7 @@ NiMH (vista extendida) Bolos/Depuración de Tratamientos + Errores Nº serie no establecido. Número de serie no válido. Tipo de infusora no establecido. @@ -47,6 +48,7 @@ + Historial de la infusora Medtronic Has cancelado el bolo después de que ya estaba enviado a la infusora. Debido a que la infusora Medtronic no soporta comando cancelar, tendrás que cancelarlo manualmente. Pon la infusora en modo suspender y luego reinicia (si todavía quieres cancelar). La aplicación recogerá los cambios en la próxima actualización (en menos de 5 minutos). No se pudo leer la basal temporal actual. @@ -69,8 +71,14 @@ Establecer la basal temporal Fijar Bolo Infusora no alcanzable + Alerta + Ahora + hace + Se necesita actualizar reloj de la bomba + Activado + Desactivado Hora del infusor actualizada diff --git a/omnipod/src/main/AndroidManifest.xml b/omnipod/src/main/AndroidManifest.xml index d520b7916a..ebf23405da 100644 --- a/omnipod/src/main/AndroidManifest.xml +++ b/omnipod/src/main/AndroidManifest.xml @@ -3,12 +3,12 @@ - - + + diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt deleted file mode 100644 index 0546589834..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodFragment.kt +++ /dev/null @@ -1,421 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod - -import android.content.Intent -import android.graphics.Color -import android.os.Bundle -import android.os.Handler -import android.text.TextUtils -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import dagger.android.support.DaggerFragment -import info.nightscout.androidaps.events.EventPreferenceChange -import info.nightscout.androidaps.interfaces.ActivePluginProvider -import info.nightscout.androidaps.interfaces.CommandQueueProvider -import info.nightscout.androidaps.logging.AAPSLogger -import info.nightscout.androidaps.logging.LTag -import info.nightscout.androidaps.plugins.bus.RxBusWrapper -import info.nightscout.androidaps.plugins.pump.common.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.defs.OmnipodStatusRequest -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodProgressStatus -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager -import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.PodManagementActivity -import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus -import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodAcknowledgeAlertsChanged -import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodPumpValuesChanged -import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodRefreshButtonState -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil -import info.nightscout.androidaps.queue.Callback -import info.nightscout.androidaps.utils.DateUtil -import info.nightscout.androidaps.utils.FabricPrivacy -import info.nightscout.androidaps.utils.T -import info.nightscout.androidaps.utils.WarnColors -import info.nightscout.androidaps.utils.alertDialogs.OKDialog -import info.nightscout.androidaps.utils.extensions.plusAssign -import info.nightscout.androidaps.utils.protection.ProtectionCheck -import info.nightscout.androidaps.utils.resources.ResourceHelper -import info.nightscout.androidaps.utils.sharedPreferences.SP -import info.nightscout.androidaps.utils.ui.UIRunnable -import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.disposables.CompositeDisposable -import io.reactivex.schedulers.Schedulers -import kotlinx.android.synthetic.main.omnipod_fragment.* -import org.apache.commons.lang3.StringUtils -import org.joda.time.DateTime -import org.joda.time.Duration -import javax.inject.Inject - -class OmnipodFragment : DaggerFragment() { - - @Inject lateinit var aapsLogger: AAPSLogger - @Inject lateinit var fabricPrivacy: FabricPrivacy - @Inject lateinit var resourceHelper: ResourceHelper - @Inject lateinit var rxBus: RxBusWrapper - @Inject lateinit var commandQueue: CommandQueueProvider - @Inject lateinit var activePlugin: ActivePluginProvider - @Inject lateinit var omnipodPumpPlugin: OmnipodPumpPlugin - @Inject lateinit var warnColors: WarnColors - @Inject lateinit var omnipodPumpStatus: OmnipodPumpStatus - @Inject lateinit var podStateManager: PodStateManager - @Inject lateinit var sp: SP - @Inject lateinit var omnipodUtil: OmnipodUtil - @Inject lateinit var rileyLinkServiceData: RileyLinkServiceData - @Inject lateinit var dateUtil: DateUtil - - // TODO somehow obtain the pumpUnreachableThreshold in order to display last connection time red or white - // @Inject lateinit var localAlertUtils: LocalAlertUtils - @Inject lateinit var protectionCheck: ProtectionCheck - - private var disposables: CompositeDisposable = CompositeDisposable() - - private val loopHandler = Handler() - private lateinit var refreshLoop: Runnable - - init { - refreshLoop = Runnable { - activity?.runOnUiThread { updateUi() } - loopHandler.postDelayed(refreshLoop, T.mins(1).msecs()) - } - } - - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - return inflater.inflate(R.layout.omnipod_fragment, container, false) - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - omnipod_pod_mgmt.setOnClickListener { - if (omnipodPumpPlugin.rileyLinkService?.verifyConfiguration() == true) { - activity?.let { activity -> - protectionCheck.queryProtection( - activity, ProtectionCheck.Protection.PREFERENCES, - UIRunnable(Runnable { startActivity(Intent(context, PodManagementActivity::class.java)) }) - ) - } - } else { - displayNotConfiguredDialog() - } - } - - omnipod_refresh.setOnClickListener { - if (omnipodPumpPlugin.rileyLinkService?.verifyConfiguration() != true) { - displayNotConfiguredDialog() - } else { - omnipod_refresh.isEnabled = false - omnipodPumpPlugin.addPodStatusRequest(OmnipodStatusRequest.GetPodState); - commandQueue.readStatus("Clicked Refresh", object : Callback() { - override fun run() { - activity?.runOnUiThread { omnipod_refresh.isEnabled = true } - } - }) - } - } - - omnipod_stats.setOnClickListener { - if (omnipodPumpPlugin.rileyLinkService?.verifyConfiguration() == true) { - startActivity(Intent(context, RileyLinkStatusActivity::class.java)) - } else { - displayNotConfiguredDialog() - } - } - - omnipod_pod_active_alerts_ack.setOnClickListener { - if (omnipodPumpPlugin.rileyLinkService?.verifyConfiguration() != true) { - displayNotConfiguredDialog() - } else { - omnipod_pod_active_alerts_ack.isEnabled = false - omnipodPumpPlugin.addPodStatusRequest(OmnipodStatusRequest.AcknowledgeAlerts); - commandQueue.readStatus("Clicked Alert Ack", null) - } - } - - omnipod_pod_debug.setOnClickListener { - if (omnipodPumpPlugin.rileyLinkService?.verifyConfiguration() != true) { - displayNotConfiguredDialog() - } else { - omnipod_pod_debug.isEnabled = false - omnipodPumpPlugin.addPodStatusRequest(OmnipodStatusRequest.GetPodPulseLog); - commandQueue.readStatus("Clicked Refresh", object : Callback() { - override fun run() { - activity?.runOnUiThread { omnipod_pod_debug.isEnabled = true } - } - }) - } - } - } - - override fun onResume() { - super.onResume() - loopHandler.postDelayed(refreshLoop, T.mins(1).msecs()) - disposables += rxBus - .toObservable(EventOmnipodRefreshButtonState::class.java) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe({ omnipod_refresh.isEnabled = it.newState }, { fabricPrivacy.logException(it) }) - disposables += rxBus - .toObservable(EventRileyLinkDeviceStatusChange::class.java) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe({ updateRileyLinkUiElements() }, { fabricPrivacy.logException(it) }) - disposables += rxBus - .toObservable(EventOmnipodPumpValuesChanged::class.java) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe({ updateOmipodUiElements() }, { fabricPrivacy.logException(it) }) - disposables += rxBus - .toObservable(EventOmnipodAcknowledgeAlertsChanged::class.java) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe({ updateAcknowledgeAlertsUiElements() }, { fabricPrivacy.logException(it) }) - disposables += rxBus - .toObservable(EventPreferenceChange::class.java) - .observeOn(Schedulers.io()) - .subscribe({ - setVisibilityOfPodDebugButton() - }, { fabricPrivacy.logException(it) }) - updateUi() - } - - fun setVisibilityOfPodDebugButton() { - val isEnabled = sp.getBoolean(OmnipodConst.Prefs.PodDebuggingOptionsEnabled, false) - - if (isEnabled) - omnipod_pod_debug.visibility = View.VISIBLE - else - omnipod_pod_debug.visibility = View.GONE - } - - private fun displayNotConfiguredDialog() { - context?.let { - OKDialog.show(it, resourceHelper.gs(R.string.omnipod_warning), - resourceHelper.gs(R.string.omnipod_error_operation_not_possible_no_configuration), null) - } - } - - override fun onPause() { - super.onPause() - disposables.clear() - loopHandler.removeCallbacks(refreshLoop) - } - - fun updateUi() { - updateRileyLinkUiElements() - updateOmipodUiElements() - } - - @Synchronized - private fun updateRileyLinkUiElements() { - aapsLogger.info(LTag.PUMP, "OmnipodFragment.setDeviceStatus") - - val rileyLinkServiceState = rileyLinkServiceData.rileyLinkServiceState - - val resourceId = rileyLinkServiceState.getResourceId() - val rileyLinkError = rileyLinkServiceData.rileyLinkError - - omnipod_rl_status.text = - when { - rileyLinkServiceState == RileyLinkServiceState.NotStarted -> resourceHelper.gs(resourceId) - rileyLinkServiceState.isConnecting -> "{fa-bluetooth-b spin} " + resourceHelper.gs(resourceId) - rileyLinkServiceState.isError && rileyLinkError == null -> "{fa-bluetooth-b} " + resourceHelper.gs(resourceId) - rileyLinkServiceState.isError && rileyLinkError != null -> "{fa-bluetooth-b} " + resourceHelper.gs(rileyLinkError.getResourceId(RileyLinkTargetDevice.Omnipod)) - else -> "{fa-bluetooth-b} " + resourceHelper.gs(resourceId) - } - omnipod_rl_status.setTextColor(if (rileyLinkServiceState.isError || rileyLinkError != null) Color.RED else Color.WHITE) - } - - fun updateOmipodUiElements() { - updateLastConnectionUiElements() - updateAcknowledgeAlertsUiElements() - updatePodStatusUiElements() - setVisibilityOfPodDebugButton() - - val errors = ArrayList(); - val rileyLinkErrorInfo = omnipodPumpStatus.errorInfo - if (rileyLinkErrorInfo != null) { - errors.add(rileyLinkErrorInfo) - } - - if (!podStateManager.hasPodState() || !podStateManager.isPodInitialized) { - if (podStateManager.hasPodState()) { - omnipod_pod_address.text = podStateManager.address.toString() - } else { - omnipod_pod_address.text = "-" - } - omnipod_pod_lot.text = "-" - omnipod_pod_tid.text = "-" - omnipod_pod_firmware_version.text = "-" - omnipod_pod_expiry.text = "-" - omnipod_basabasalrate.text = "-" - omnipod_total_delivered.text = "-" - omnipod_reservoir.text = "-" - omnipod_tempbasal.text = "-" - omnipod_lastbolus.text = "-" - omnipod_lastconnection.setTextColor(Color.WHITE) - } else { - omnipod_pod_address.text = podStateManager.address.toString() - omnipod_pod_lot.text = podStateManager.lot.toString() - omnipod_pod_tid.text = podStateManager.tid.toString() - omnipod_pod_firmware_version.text = resourceHelper.gs(R.string.omnipod_pod_firmware_version_value, podStateManager.pmVersion.toString(), podStateManager.piVersion.toString()) - val expiresAt = podStateManager.expiresAt - omnipod_pod_expiry.text = if (expiresAt == null) "???" else dateUtil.dateAndTimeString(expiresAt.toDate()) - - if (podStateManager.hasFaultEvent()) { - val faultEventCode = podStateManager.faultEvent.faultEventCode - errors.add(resourceHelper.gs(R.string.omnipod_pod_status_pod_fault_description, faultEventCode.value, faultEventCode.name)) - } - - // last bolus - if (podStateManager.lastBolusStartTime != null && podStateManager.lastBolusAmount != null) { - val ago = readableDuration(podStateManager.lastBolusStartTime) - omnipod_lastbolus.text = resourceHelper.gs(R.string.omnipod_last_bolus, omnipodPumpPlugin.pumpType.determineCorrectBolusSize(podStateManager.lastBolusAmount), resourceHelper.gs(R.string.insulin_unit_shortname), ago) - } else { - omnipod_lastbolus.text = "-" - } - - // base basal rate - omnipod_basabasalrate.text = resourceHelper.gs(R.string.pump_basebasalrate, omnipodPumpPlugin.pumpType.determineCorrectBasalSize(omnipodPumpPlugin.baseBasalRate)) - - omnipod_tempbasal.text = activePlugin.activeTreatments - .getTempBasalFromHistory(System.currentTimeMillis())?.toStringFull() ?: "-" - - // total delivered - omnipod_total_delivered.text = if (podStateManager.isPodActivationCompleted && podStateManager.totalInsulinDelivered != null) { // Null check for backwards compatibility - resourceHelper.gs(R.string.omnipod_total_delivered, podStateManager.totalInsulinDelivered - OmnipodConst.POD_SETUP_UNITS); - } else { - "-" - } - - // reservoir - if (podStateManager.reservoirLevel == null) { - omnipod_reservoir.text = resourceHelper.gs(R.string.omnipod_reservoir_over50) - omnipod_reservoir.setTextColor(Color.WHITE) - } else { - omnipod_reservoir.text = resourceHelper.gs(R.string.omnipod_reservoir_left, podStateManager.reservoirLevel) - warnColors.setColorInverse(omnipod_reservoir, podStateManager.reservoirLevel, 50.0, 20.0) - } - } - - if (errors.size == 0) { - omnipod_errors.text = "-" - omnipod_errors.setTextColor(Color.WHITE) - } else { - omnipod_errors.text = StringUtils.join(errors, System.lineSeparator()) - omnipod_errors.setTextColor(Color.RED) - } - - val status = commandQueue.spannedStatus() - if (status.toString() == "") { - omnipod_queue.visibility = View.GONE - } else { - omnipod_queue.visibility = View.VISIBLE - omnipod_queue.text = status - } - - omnipod_refresh.isEnabled = podStateManager.isPodInitialized && podStateManager.podProgressStatus.isAtLeast(PodProgressStatus.PAIRING_COMPLETED) - } - - private fun updateLastConnectionUiElements() { - if (podStateManager.isPodInitialized && podStateManager.lastSuccessfulCommunication != null) { // Null check for backwards compatibility - omnipod_lastconnection.text = readableDuration(podStateManager.lastSuccessfulCommunication) - omnipod_lastconnection.setTextColor(Color.WHITE) - /* - // TODO - if (omnipodPumpPlugin.isUnreachableAlertTimeoutExceeded(localAlertUtils.pumpUnreachableThreshold())) { - omnipod_lastconnection.setTextColor(Color.RED) - } else { - omnipod_lastconnection.setTextColor(Color.WHITE) - } - */ - } else { - omnipod_lastconnection.setTextColor(Color.WHITE) - if (podStateManager.hasPodState() && podStateManager.lastSuccessfulCommunication != null) { - omnipod_lastconnection.text = readableDuration(podStateManager.lastSuccessfulCommunication) - } else { - omnipod_lastconnection.text = "-" - } - } - } - - private fun updatePodStatusUiElements() { - if (!podStateManager.hasPodState()) { - omnipod_pod_status.text = resourceHelper.gs(R.string.omnipod_pod_status_no_active_pod) - } else if (!podStateManager.isPodActivationCompleted) { - if (!podStateManager.isPodInitialized) { - omnipod_pod_status.text = resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_pair_and_prime) - } else { - if (PodProgressStatus.ACTIVATION_TIME_EXCEEDED == podStateManager.podProgressStatus) { - omnipod_pod_status.text = resourceHelper.gs(R.string.omnipod_pod_status_activation_time_exceeded) - } else if (podStateManager.podProgressStatus.isBefore(PodProgressStatus.PRIMING_COMPLETED)) { - omnipod_pod_status.text = resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_pair_and_prime) - } else { - omnipod_pod_status.text = resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_cannula_insertion) - } - } - } else { - if (podStateManager.podProgressStatus.isRunning) { - if (podStateManager.isSuspended) { - omnipod_pod_status.text = resourceHelper.gs(R.string.omnipod_pod_status_suspended) - } else { - omnipod_pod_status.text = resourceHelper.gs(R.string.omnipod_pod_status_running) - } - } else if (podStateManager.podProgressStatus == PodProgressStatus.FAULT_EVENT_OCCURRED) { - omnipod_pod_status.text = resourceHelper.gs(R.string.omnipod_pod_status_pod_fault) - } else if (podStateManager.podProgressStatus == PodProgressStatus.INACTIVE) { - omnipod_pod_status.text = resourceHelper.gs(R.string.omnipod_pod_status_inactive) - } else { - omnipod_pod_status.text = podStateManager.podProgressStatus.toString() - } - } - - if (!podStateManager.isPodActivationCompleted || podStateManager.isPodDead || podStateManager.isSuspended) { - omnipod_pod_status.setTextColor(Color.RED) - } else { - omnipod_pod_status.setTextColor(Color.WHITE) - } - } - - private fun updateAcknowledgeAlertsUiElements() { - if (podStateManager.isPodInitialized && podStateManager.hasActiveAlerts()) { - omnipod_pod_active_alerts_ack.isEnabled = true - omnipod_pod_active_alerts.text = TextUtils.join(System.lineSeparator(), omnipodUtil.getTranslatedActiveAlerts(podStateManager)) - } else { - omnipod_pod_active_alerts_ack.isEnabled = false - omnipod_pod_active_alerts.text = "-" - } - } - - private fun readableDuration(dateTime: DateTime): String { - val minutes = Duration(dateTime, DateTime.now()).standardMinutes.toInt() - when { - minutes == 0 -> { - return resourceHelper.gs(R.string.omnipod_moments_ago) - } - - minutes < 60 -> { - return resourceHelper.gs(R.string.omnipod_time_ago, resourceHelper.gq(R.plurals.omnipod_minutes, minutes, minutes)) - } - - minutes < 1440 -> { - val hours = minutes / 60 - val minutesLeft = minutes % 60 - if (minutesLeft > 0) - return resourceHelper.gs(R.string.omnipod_time_ago, - resourceHelper.gs(R.string.omnipod_composite_time, resourceHelper.gq(R.plurals.omnipod_hours, hours, hours), resourceHelper.gq(R.plurals.omnipod_minutes, minutesLeft, minutesLeft))) - return resourceHelper.gs(R.string.omnipod_time_ago, resourceHelper.gq(R.plurals.omnipod_hours, hours, hours)) - } - - else -> { - val hours = minutes / 60 - val days = hours / 24 - val hoursLeft = hours % 24 - if (hoursLeft > 0) - return resourceHelper.gs(R.string.omnipod_time_ago, - resourceHelper.gs(R.string.omnipod_composite_time, resourceHelper.gq(R.plurals.omnipod_days, days, days), resourceHelper.gq(R.plurals.omnipod_hours, hoursLeft, hoursLeft))) - return resourceHelper.gs(R.string.omnipod_time_ago, resourceHelper.gq(R.plurals.omnipod_days, days, days)) - } - } - } - -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java index 1a98a8e6f5..0cbb4f3d34 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java @@ -5,20 +5,25 @@ import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; +import android.os.Handler; import android.os.IBinder; import android.os.SystemClock; import androidx.annotation.NonNull; import org.jetbrains.annotations.NotNull; +import org.joda.time.DateTime; +import org.joda.time.Duration; +import org.json.JSONException; +import org.json.JSONObject; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.GregorianCalendar; -import java.util.HashSet; +import java.util.Date; +import java.util.Iterator; import java.util.List; -import java.util.Set; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Supplier; import javax.inject.Inject; import javax.inject.Singleton; @@ -28,8 +33,11 @@ import info.nightscout.androidaps.activities.ErrorHelperActivity; 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.db.Treatment; +import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventAppInitialized; import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventRefreshOverview; @@ -37,43 +45,50 @@ import info.nightscout.androidaps.interfaces.ActivePluginProvider; import info.nightscout.androidaps.interfaces.CommandQueueProvider; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.interfaces.PumpDescription; +import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.interfaces.PumpPluginBase; import info.nightscout.androidaps.logging.AAPSLogger; import info.nightscout.androidaps.logging.LTag; import info.nightscout.androidaps.plugins.bus.RxBusWrapper; +import info.nightscout.androidaps.plugins.common.ManufacturerType; import info.nightscout.androidaps.plugins.general.actions.defs.CustomAction; import info.nightscout.androidaps.plugins.general.actions.defs.CustomActionType; import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification; +import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress; import info.nightscout.androidaps.plugins.general.overview.notifications.Notification; -import info.nightscout.androidaps.plugins.pump.common.PumpPluginAbstract; -import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus; import info.nightscout.androidaps.plugins.pump.common.data.TempBasalPair; import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst; +import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkPumpDevice; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkPumpInfo; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.ResetRileyLinkConfigurationTask; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.ServiceTaskExecutor; import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoRecentPulseLog; import info.nightscout.androidaps.plugins.pump.omnipod.data.ActiveBolus; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodCommandType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodCustomActionType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodPumpPluginInterface; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodStatusRequest; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.comm.AapsOmnipodManager; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.ui.OmnipodUIComm; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.ui.OmnipodUITask; -import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodPumpValuesChanged; -import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodRefreshButtonState; -import info.nightscout.androidaps.plugins.pump.omnipod.service.RileyLinkOmnipodService; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil; +import info.nightscout.androidaps.plugins.pump.omnipod.data.RLHistoryItemOmnipod; +import info.nightscout.androidaps.plugins.pump.omnipod.definition.OmnipodCommandType; +import info.nightscout.androidaps.plugins.pump.omnipod.definition.OmnipodCustomActionType; +import info.nightscout.androidaps.plugins.pump.omnipod.definition.OmnipodStatusRequestType; +import info.nightscout.androidaps.plugins.pump.omnipod.definition.OmnipodStorageKeys; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.service.ExpirationReminderBuilder; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoRecentPulseLog; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertConfiguration; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged; +import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodTbrChanged; +import info.nightscout.androidaps.plugins.pump.omnipod.manager.AapsOmnipodManager; +import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.service.RileyLinkOmnipodService; +import info.nightscout.androidaps.plugins.pump.omnipod.ui.OmnipodFragment; +import info.nightscout.androidaps.plugins.pump.omnipod.util.AapsOmnipodUtil; +import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodAlertUtil; import info.nightscout.androidaps.utils.DateUtil; +import info.nightscout.androidaps.utils.DecimalFormatter; import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.Round; import info.nightscout.androidaps.utils.TimeChangeType; @@ -88,32 +103,46 @@ import io.reactivex.schedulers.Schedulers; * @author Andy Rozman (andy.rozman@gmail.com) */ @Singleton -public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPumpPluginInterface, RileyLinkPumpDevice { +public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface, RileyLinkPumpDevice { + private static final long RILEY_LINK_CONNECT_TIMEOUT_MILLIS = 3 * 60 * 1000L; // 3 minutes + private static final long STATUS_CHECK_INTERVAL_MILLIS = 60 * 1000L; // 1 minute + private final PodStateManager podStateManager; private final RileyLinkServiceData rileyLinkServiceData; private final ServiceTaskExecutor serviceTaskExecutor; - private final OmnipodPumpStatus omnipodPumpStatus; private final AapsOmnipodManager aapsOmnipodManager; - private final OmnipodUtil omnipodUtil; + private final AapsOmnipodUtil aapsOmnipodUtil; + private final RileyLinkUtil rileyLinkUtil; + private final OmnipodAlertUtil omnipodAlertUtil; + private final AAPSLogger aapsLogger; + private final RxBusWrapper rxBus; + private final ActivePluginProvider activePlugin; + private final Context context; + private final FabricPrivacy fabricPrivacy; + private final ResourceHelper resourceHelper; + private final SP sp; + private final DateUtil dateUtil; + private final PumpDescription pumpDescription; + private final ServiceConnection serviceConnection; + private final PumpType pumpType = PumpType.Insulet_Omnipod; - private CompositeDisposable disposable = new CompositeDisposable(); + private final List customActions = new ArrayList<>(); + private final List statusRequestList = new ArrayList<>(); + private final CompositeDisposable disposables = new CompositeDisposable(); // variables for handling statuses and history - protected boolean firstRun = true; - protected boolean isRefresh = false; - private boolean isInitialized = false; - + private boolean firstRun = true; + private boolean hasTimeDateOrTimeZoneChanged = false; + private final boolean displayConnectionMessages = false; private RileyLinkOmnipodService rileyLinkOmnipodService; - - private boolean isBusy = false; - // TODO it seems that we never add anything to this list? - // I Wouldn't know why we need it anyway - protected List busyTimestamps = new ArrayList<>(); - protected boolean hasTimeDateOrTimeZoneChanged = false; - private int timeChangeRetries = 0; - private Profile currentProfile; - private long nextPodCheck = 0L; + private boolean busy = false; + private int timeChangeRetries; + private long nextPodCheck; private boolean sentIdToFirebase; + private long lastConnectionTimeMillis; + private final Handler loopHandler = new Handler(); + + private final Runnable statusChecker; @Inject public OmnipodPumpPlugin( @@ -124,7 +153,6 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump ResourceHelper resourceHelper, ActivePluginProvider activePlugin, SP sp, - OmnipodPumpStatus omnipodPumpStatus, PodStateManager podStateManager, AapsOmnipodManager aapsOmnipodManager, CommandQueueProvider commandQueue, @@ -132,7 +160,9 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump RileyLinkServiceData rileyLinkServiceData, ServiceTaskExecutor serviceTaskExecutor, DateUtil dateUtil, - OmnipodUtil omnipodUtil + AapsOmnipodUtil aapsOmnipodUtil, + RileyLinkUtil rileyLinkUtil, + OmnipodAlertUtil omnipodAlertUtil ) { super(new PluginDescription() // .mainType(PluginType.PUMP) // @@ -141,24 +171,29 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump .shortName(R.string.omnipod_name_short) // .preferencesId(R.xml.pref_omnipod) // .description(R.string.description_pump_omnipod), // - PumpType.Insulet_Omnipod, - injector, resourceHelper, aapsLogger, commandQueue, rxBus, activePlugin, sp, context, fabricPrivacy, dateUtil); + injector, aapsLogger, resourceHelper, commandQueue); + this.aapsLogger = aapsLogger; + this.rxBus = rxBus; + this.activePlugin = activePlugin; + this.context = context; + this.fabricPrivacy = fabricPrivacy; + this.resourceHelper = resourceHelper; + this.sp = sp; + this.dateUtil = dateUtil; this.podStateManager = podStateManager; this.rileyLinkServiceData = rileyLinkServiceData; this.serviceTaskExecutor = serviceTaskExecutor; - this.omnipodPumpStatus = omnipodPumpStatus; this.aapsOmnipodManager = aapsOmnipodManager; - this.omnipodUtil = omnipodUtil; + this.aapsOmnipodUtil = aapsOmnipodUtil; + this.rileyLinkUtil = rileyLinkUtil; + this.omnipodAlertUtil = omnipodAlertUtil; + + pumpDescription = new PumpDescription(pumpType); + + customActions.add(new CustomAction( + R.string.omnipod_custom_action_reset_rileylink, OmnipodCustomActionType.RESET_RILEY_LINK_CONFIGURATION, true)); - displayConnectionMessages = false; this.serviceConnection = new ServiceConnection() { - - @Override - public void onServiceDisconnected(ComponentName name) { - aapsLogger.debug(LTag.PUMP, "RileyLinkOmnipodService is disconnected"); - rileyLinkOmnipodService = null; - } - @Override public void onServiceConnected(ComponentName name, IBinder service) { aapsLogger.debug(LTag.PUMP, "RileyLinkOmnipodService is connected"); @@ -178,34 +213,88 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump } }).start(); } - }; - } - public PodStateManager getPodStateManager() { - return podStateManager; + @Override + public void onServiceDisconnected(ComponentName name) { + aapsLogger.debug(LTag.PUMP, "RileyLinkOmnipodService is disconnected"); + rileyLinkOmnipodService = null; + } + }; + + statusChecker = new Runnable() { + @Override public void run() { + if (podStateManager.isPodRunning() && !podStateManager.isSuspended()) { + aapsOmnipodManager.cancelSuspendedFakeTbrIfExists(); + } else { + aapsOmnipodManager.createSuspendedFakeTbrIfNotExists(); + } + + if (!getCommandQueue().statusInQueue()) { + if (!OmnipodPumpPlugin.this.statusRequestList.isEmpty()) { + getCommandQueue().readStatus("Status Refresh Requested", null); + } else if (OmnipodPumpPlugin.this.hasTimeDateOrTimeZoneChanged) { + getCommandQueue().readStatus("Date or Time Zone Changed", null); + } else if (!OmnipodPumpPlugin.this.verifyPodAlertConfiguration()) { + getCommandQueue().readStatus("Expiration Alerts Changed", null); + } + } + + doPodCheck(); + + loopHandler.postDelayed(this, STATUS_CHECK_INTERVAL_MILLIS); + } + }; } @Override protected void onStart() { + super.onStart(); + + loopHandler.postDelayed(statusChecker, STATUS_CHECK_INTERVAL_MILLIS); + // We can't do this in PodStateManager itself, because JodaTimeAndroid.init() hasn't been called yet // When PodStateManager is created, which causes an IllegalArgumentException for DateTimeZones not being recognized - // TODO either find a more elegant solution, or at least make sure this is the right place to do this podStateManager.loadPodState(); - disposable.add(rxBus + lastConnectionTimeMillis = sp.getLong( + RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L); + + Intent intent = new Intent(context, RileyLinkOmnipodService.class); + context.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); + + disposables.add(rxBus + .toObservable(EventAppExit.class) + .observeOn(Schedulers.io()) + .subscribe(event -> context.unbindService(serviceConnection), fabricPrivacy::logException) + ); + disposables.add(rxBus + .toObservable(EventOmnipodTbrChanged.class) + .observeOn(Schedulers.io()) + .subscribe(event -> updateAapsTbr(), fabricPrivacy::logException) + ); + disposables.add(rxBus .toObservable(EventPreferenceChange.class) .observeOn(Schedulers.io()) .subscribe(event -> { - if ((event.isChanged(getResourceHelper(), R.string.key_omnipod_beep_basal_enabled)) || - (event.isChanged(getResourceHelper(), R.string.key_omnipod_beep_bolus_enabled)) || - (event.isChanged(getResourceHelper(), R.string.key_omnipod_beep_tbr_enabled)) || - (event.isChanged(getResourceHelper(), R.string.key_omnipod_pod_debugging_options_enabled)) || - (event.isChanged(getResourceHelper(), R.string.key_omnipod_beep_smb_enabled)) || - (event.isChanged(getResourceHelper(), R.string.key_omnipod_timechange_enabled))) - rileyLinkOmnipodService.verifyConfiguration(); + if ((event.isChanged(getResourceHelper(), R.string.key_omnipod_basal_beeps_enabled)) || + (event.isChanged(getResourceHelper(), R.string.key_omnipod_bolus_beeps_enabled)) || + (event.isChanged(getResourceHelper(), R.string.key_omnipod_tbr_beeps_enabled)) || + (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_time_change_event_enabled))) { + aapsOmnipodManager.reloadSettings(); + } else if (event.isChanged(getResourceHelper(), R.string.key_omnipod_expiration_reminder_enabled) || + event.isChanged(getResourceHelper(), R.string.key_omnipod_expiration_reminder_hours_before_shutdown) || + event.isChanged(getResourceHelper(), R.string.key_omnipod_low_reservoir_alert_enabled) || + event.isChanged(getResourceHelper(), R.string.key_omnipod_low_reservoir_alert_units)) { + if (!verifyPodAlertConfiguration() && !getCommandQueue().statusInQueue()) { + getCommandQueue().readStatus("Expiration Alerts Changed", null); + } + } }, fabricPrivacy::logException) ); - disposable.add(rxBus + disposables.add(rxBus .toObservable(EventAppInitialized.class) .observeOn(Schedulers.io()) .subscribe(event -> { @@ -213,71 +302,42 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump // If so, add it to history // Needs to be done after EventAppInitialized because otherwise, TreatmentsPlugin.onStart() hasn't been called yet // so it didn't initialize a TreatmentService yet, resulting in a NullPointerException - if (sp.contains(OmnipodConst.Prefs.ActiveBolus)) { - String activeBolusString = sp.getString(OmnipodConst.Prefs.ActiveBolus, ""); + if (sp.contains(OmnipodStorageKeys.Preferences.ACTIVE_BOLUS)) { + String activeBolusString = sp.getString(OmnipodStorageKeys.Preferences.ACTIVE_BOLUS, ""); aapsLogger.warn(LTag.PUMP, "Found active bolus in SP: {}. Adding Treatment.", activeBolusString); try { - ActiveBolus activeBolus = omnipodUtil.getGsonInstance().fromJson(activeBolusString, ActiveBolus.class); + ActiveBolus activeBolus = aapsOmnipodUtil.getGsonInstance().fromJson(activeBolusString, ActiveBolus.class); aapsOmnipodManager.addBolusToHistory(activeBolus.toDetailedBolusInfo(aapsLogger)); } catch (Exception ex) { aapsLogger.error(LTag.PUMP, "Failed to add active bolus to history", ex); } - sp.remove(OmnipodConst.Prefs.ActiveBolus); + sp.remove(OmnipodStorageKeys.Preferences.ACTIVE_BOLUS); } }, fabricPrivacy::logException) ); - - super.onStart(); } - @Override - protected void onStop() { - disposable.clear(); - super.onStop(); - } - - private String getLogPrefix() { - return "OmnipodPlugin::"; - } - - @Override - public void initPumpStatusData() { - omnipodPumpStatus.lastConnection = sp.getLong(RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L); - omnipodPumpStatus.lastDataTime = omnipodPumpStatus.lastConnection; - omnipodPumpStatus.previousConnection = omnipodPumpStatus.lastConnection; - - if (rileyLinkOmnipodService != null) rileyLinkOmnipodService.verifyConfiguration(); - - aapsLogger.debug(LTag.PUMP, "initPumpStatusData: " + this.omnipodPumpStatus); - - // set first Omnipod Pump Start - if (!sp.contains(OmnipodConst.Statistics.FirstPumpStart)) { - sp.putLong(OmnipodConst.Statistics.FirstPumpStart, System.currentTimeMillis()); + 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()) { + if (activePlugin.getActiveTreatments().isTempBasalInProgress() && !aapsOmnipodManager.hasSuspendedFakeTbr()) { + aapsOmnipodManager.reportCancelledTbr(); + } } } @Override - public void onStartCustomActions() { - // check status every minute (if any status needs refresh we send readStatus command) - new Thread(() -> { - do { - SystemClock.sleep(60000); + protected void onStop() { + super.onStop(); + aapsLogger.debug(LTag.PUMP, "OmnipodPumpPlugin.onStop()"); - if (this.isInitialized) { - clearBusyQueue(); - } + loopHandler.removeCallbacks(statusChecker); - if (!this.omnipodStatusRequestList.isEmpty() || this.hasTimeDateOrTimeZoneChanged) { - if (!getCommandQueue().statusInQueue()) { - getCommandQueue().readStatus("Status Refresh Requested", null); - } - } + context.unbindService(serviceConnection); - doPodCheck(); - - } while (serviceRunning); - - }).start(); + disposables.clear(); } private void doPodCheck() { @@ -287,64 +347,59 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump rxBus.send(new EventNewNotification(notification)); } else { rxBus.send(new EventDismissNotification(Notification.OMNIPOD_POD_NOT_ATTACHED)); + + if (podStateManager.isSuspended()) { + Notification notification = new Notification(Notification.OMNIPOD_POD_SUSPENDED, resourceHelper.gs(R.string.omnipod_error_pod_suspended), Notification.NORMAL); + rxBus.send(new EventNewNotification(notification)); + } else { + rxBus.send(new EventDismissNotification(Notification.OMNIPOD_POD_SUSPENDED)); + } } this.nextPodCheck = DateTimeUtil.getTimeInFutureFromMinutes(15); } } - @Override - public Class getServiceClass() { - return RileyLinkOmnipodService.class; - } - - @Override - public PumpStatus getPumpStatusData() { - return this.omnipodPumpStatus; - } - - @Override - public String deviceID() { - return "Omnipod"; - } - - // Pump Plugin - - private boolean isServiceSet() { - return rileyLinkOmnipodService != null; - } - + // TODO is this correct? @Override public boolean isInitialized() { - if (displayConnectionMessages) - aapsLogger.debug(LTag.PUMP, getLogPrefix() + "isInitialized"); - return isServiceSet() && isInitialized; + return isConnected() && podStateManager.isPodActivationCompleted(); } @Override - public boolean isBusy() { + public boolean isConnected() { + return rileyLinkOmnipodService != null && rileyLinkOmnipodService.isInitialized(); + } + + @Override + public boolean isConnecting() { + return rileyLinkOmnipodService == null || !rileyLinkOmnipodService.isInitialized(); + } + + @Override + public boolean isHandshakeInProgress() { if (displayConnectionMessages) - aapsLogger.debug(LTag.PUMP, getLogPrefix() + "isBusy"); - - if (isServiceSet()) { - - if (isBusy || !podStateManager.isPodRunning()) - return true; - - if (busyTimestamps.size() > 0) { - - clearBusyQueue(); - - return (busyTimestamps.size() > 0); - } - } - + aapsLogger.debug(LTag.PUMP, "isHandshakeInProgress [OmnipodPumpPlugin] - default (empty) implementation."); return false; } + // TODO is this correct? + @Override + public boolean isBusy() { + return busy || rileyLinkOmnipodService == null || !podStateManager.isPodRunning(); + } + + @Override public void setBusy(boolean busy) { + this.busy = busy; + } + + @Override + public boolean isSuspended() { + return !podStateManager.isPodRunning() || podStateManager.isSuspended(); + } + @Override public void triggerPumpConfigurationChangedEvent() { - rxBus.send(new EventOmnipodPumpValuesChanged()); rxBus.send(new EventRileyLinkDeviceStatusChange()); } @@ -361,108 +416,83 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump return new RileyLinkPumpInfo(pumpDescription, frequency, connectedModel, serialNumber); } + // Required by RileyLinkPumpDevice interface. + // Kind of redundant because we also store last successful and last failed communication in PodStateManager + + /** + * Get the last communication time with the Pod. In the current implementation, this + * doesn't have to mean that a command was successfully executed as the Pod could also return an ErrorResponse or PodFaultEvent + * For getting the last time a command was successfully executed, use PodStateManager.getLastSuccessfulCommunication + */ @Override public long getLastConnectionTimeMillis() { - return omnipodPumpStatus.lastConnection; + return lastConnectionTimeMillis; } + // Required by RileyLinkPumpDevice interface. + // Kind of redundant because we also store last successful and last failed communication in PodStateManager + + /** + * Set the last communication time with the Pod to now. In the current implementation, this + * doesn't have to mean that a command was successfully executed as the Pod could also return an ErrorResponse or PodFaultEvent + * For setting the last time a command was successfully executed, use PodStateManager.setLastSuccessfulCommunication + */ @Override public void setLastCommunicationToNow() { - omnipodPumpStatus.setLastCommunicationToNow(); - } - - public OmnipodUIComm getDeviceCommandExecutor() { - return rileyLinkOmnipodService.getDeviceCommandExecutor(); - } - - private synchronized void clearBusyQueue() { - - if (busyTimestamps.size() == 0) { - return; - } - - Set deleteFromQueue = new HashSet<>(); - - for (Long busyTimestamp : busyTimestamps) { - - if (System.currentTimeMillis() > busyTimestamp) { - deleteFromQueue.add(busyTimestamp); - } - } - - if (deleteFromQueue.size() == busyTimestamps.size()) { - busyTimestamps.clear(); - //setEnableCustomAction(MedtronicCustomActionType.ClearBolusBlock, false); - } - - if (deleteFromQueue.size() > 0) { - busyTimestamps.removeAll(deleteFromQueue); - } - - } - - @Override - public boolean isConnected() { - if (displayConnectionMessages) - aapsLogger.debug(LTag.PUMP, getLogPrefix() + "isConnected"); - return isServiceSet() && rileyLinkOmnipodService.isInitialized(); - } - - @Override - public boolean isConnecting() { - if (displayConnectionMessages) - aapsLogger.debug(LTag.PUMP, getLogPrefix() + "isConnecting"); - return !isServiceSet() || !rileyLinkOmnipodService.isInitialized(); - } - - @Override - public boolean isSuspended() { - return !podStateManager.isPodRunning() || podStateManager.isSuspended(); + lastConnectionTimeMillis = System.currentTimeMillis(); } + // We abuse getPumpStatus to squeeze commands in the queue + // The only actual status requests we send to the Pod are on startup (in initializeAfterRileyLinkConnection) + // And when the user explicitly requested it by clicking the Refresh button on the Omnipod tab + // We don't do periodical status requests because that can drain the Pod's battery + // However that should be fine because we get a StatusResponse from all insulin commands sent to the Pod @Override public void getPumpStatus() { if (firstRun) { - initializePump(!isRefresh); - triggerUIChange(); + initializeAfterRileyLinkConnection(); + } else if (!statusRequestList.isEmpty()) { + Iterator iterator = statusRequestList.iterator(); - } else if (!omnipodStatusRequestList.isEmpty()) { - - List removeList = new ArrayList<>(); - - for (OmnipodStatusRequest omnipodStatusRequest : omnipodStatusRequestList) { - if (omnipodStatusRequest == OmnipodStatusRequest.GetPodPulseLog) { - OmnipodUITask omnipodUITask = getDeviceCommandExecutor().executeCommand(omnipodStatusRequest.getCommandType()); - - PodInfoRecentPulseLog result = (PodInfoRecentPulseLog) omnipodUITask.returnDataObject; - - if (result == null) { - aapsLogger.warn(LTag.PUMP, "Result was null."); - } else { - aapsLogger.warn(LTag.PUMP, "Result was NOT null."); - - Intent i = new Intent(context, ErrorHelperActivity.class); - i.putExtra("soundid", 0); - i.putExtra("status", "Pulse Log (copied to clipboard):\n" + result.toString()); - i.putExtra("title", resourceHelper.gs(R.string.omnipod_warning)); - i.putExtra("clipboardContent", result.toString()); - i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - context.startActivity(i); - -// OKDialog.show(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.action), -// "Pulse Log:\n" + result.toString(), null); - } - - } else { - getDeviceCommandExecutor().executeCommand(omnipodStatusRequest.getCommandType()); + while (iterator.hasNext()) { + OmnipodStatusRequestType statusRequest = iterator.next(); + switch (statusRequest) { + case GET_PULSE_LOG: + try { + PodInfoRecentPulseLog result = executeCommand(OmnipodCommandType.GET_POD_PULSE_LOG, aapsOmnipodManager::readPulseLog); + Intent i = new Intent(context, ErrorHelperActivity.class); + i.putExtra("soundid", 0); + i.putExtra("status", "Pulse Log (copied to clipboard):\n" + result.toString()); + i.putExtra("title", resourceHelper.gs(R.string.omnipod_warning)); + i.putExtra("clipboardContent", result.toString()); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(i); + } catch (Exception ex) { + aapsLogger.warn(LTag.PUMP, "Failed to retrieve pulse log", ex); + Intent i = new Intent(context, ErrorHelperActivity.class); + i.putExtra("soundid", 0); + i.putExtra("status", "Failed to retrieve pulse log"); + i.putExtra("title", resourceHelper.gs(R.string.omnipod_warning)); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(i); + } + break; + case ACKNOWLEDGE_ALERTS: + executeCommand(OmnipodCommandType.ACKNOWLEDGE_ALERTS, aapsOmnipodManager::acknowledgeAlerts); + break; + case GET_POD_STATE: + executeCommand(OmnipodCommandType.GET_POD_STATUS, aapsOmnipodManager::getPodStatus); + break; + case SUSPEND_DELIVERY: + executeCommand(OmnipodCommandType.SUSPEND_DELIVERY, aapsOmnipodManager::suspendDelivery); + break; + default: + aapsLogger.error(LTag.PUMP, "Unknown status request: " + statusRequest.name()); } - removeList.add(omnipodStatusRequest); + iterator.remove(); } - - omnipodStatusRequestList.removeAll(removeList); - } else if (this.hasTimeDateOrTimeZoneChanged) { - OmnipodUITask omnipodUITask = getDeviceCommandExecutor().executeCommand(OmnipodCommandType.SetTime); + PumpEnactResult result = executeCommand(OmnipodCommandType.SET_TIME, aapsOmnipodManager::setTime); - if (omnipodUITask.wasCommandSuccessful()) { + if (result.success) { this.hasTimeDateOrTimeZoneChanged = false; timeChangeRetries = 0; @@ -480,117 +510,338 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump timeChangeRetries = 0; } } + } else if (!verifyPodAlertConfiguration()) { + Duration expirationReminderTimeBeforeShutdown = omnipodAlertUtil.getExpirationReminderTimeBeforeShutdown(); + Integer lowReservoirAlertUnits = omnipodAlertUtil.getLowReservoirAlertUnits(); + + List alertConfigurations = new ExpirationReminderBuilder(podStateManager) // + .expirationAdvisory(expirationReminderTimeBeforeShutdown != null, + Optional.ofNullable(expirationReminderTimeBeforeShutdown).orElse(Duration.ZERO)) // + .lowReservoir(lowReservoirAlertUnits != null, Optional.ofNullable(lowReservoirAlertUnits).orElse(0)) // + .build(); + + PumpEnactResult result = executeCommand(OmnipodCommandType.CONFIGURE_ALERTS, () -> aapsOmnipodManager.configureAlerts(alertConfigurations)); + + if (result.success) { + aapsLogger.info(LTag.PUMP, "Successfully configured alerts in Pod"); + + podStateManager.setExpirationAlertTimeBeforeShutdown(expirationReminderTimeBeforeShutdown); + podStateManager.setLowReservoirAlertUnits(lowReservoirAlertUnits); + + Notification notification = new Notification( + Notification.OMNIPOD_POD_ALERTS_UPDATED, + resourceHelper.gs(R.string.omnipod_expiration_alerts_updated), + Notification.INFO, 60); + rxBus.send(new EventNewNotification(notification)); + } else { + aapsLogger.warn(LTag.PUMP, "Failed to configure alerts in Pod"); + } } } - public void setBusy(boolean busy) { - this.isBusy = busy; - } + @NotNull + @Override + public PumpEnactResult setNewBasalProfile(Profile profile) { + PumpEnactResult result = executeCommand(OmnipodCommandType.SET_BASAL_PROFILE, () -> aapsOmnipodManager.setBasalProfile(profile)); - private void getPodPumpStatus() { - // TODO read pod status - aapsLogger.error(LTag.PUMP, "getPodPumpStatus() NOT IMPLEMENTED"); - } + aapsLogger.info(LTag.PUMP, "Basal Profile was set: " + result.success); - List omnipodStatusRequestList = new ArrayList<>(); - - public void addPodStatusRequest(OmnipodStatusRequest pumpStatusRequest) { - if (pumpStatusRequest == OmnipodStatusRequest.ResetState) { - resetStatusState(); - } else { - omnipodStatusRequestList.add(pumpStatusRequest); - } - } - - public void resetStatusState() { - firstRun = true; - isRefresh = true; - } - - // FIXME do we actually need this? If a user presses refresh during an action, - // I suppose the GetStatusCommand would just be queued? - private void setRefreshButtonEnabled(boolean enabled) { - rxBus.send(new EventOmnipodRefreshButtonState(enabled)); - } - - private void initializePump(boolean realInit) { - aapsLogger.info(LTag.PUMP, getLogPrefix() + "initializePump - start"); - - // TODO ccc - //OmnipodPumpStatus podPumpStatus = getPodPumpStatusObject(); - - setRefreshButtonEnabled(false); - - if (podStateManager.isPodInitialized()) { - aapsLogger.debug(LTag.PUMP, "PodStateManager (saved): " + podStateManager); - // TODO handle if session state too old - getPodPumpStatus(); - } else { - aapsLogger.debug(LTag.PUMP, "No Pod running"); - } - - finishAction("Omnipod Pump"); - - if (!sentIdToFirebase) { - Bundle params = new Bundle(); - params.putString("version", BuildConfig.VERSION); - - getFabricPrivacy().getFirebaseAnalytics().logEvent("OmnipodPumpInit", params); - - sentIdToFirebase = true; - } - - isInitialized = true; - - this.firstRun = false; + return result; } @Override public boolean isThisProfileSet(Profile profile) { - - // TODO status was not yet read from pod - // TODO maybe not possible, need to see how we will handle that - if (currentProfile == null) { - this.currentProfile = profile; + if (!podStateManager.isPodActivationCompleted()) { + // When no Pod is active, return true here in order to prevent AAPS from setting a profile + // When we activate a new Pod, we just use ProfileFunction to set the currently active profile return true; } - - return (currentProfile.areProfileBasalPatternsSame(profile)); + return podStateManager.getBasalSchedule().equals(AapsOmnipodManager.mapProfileToBasalSchedule(profile)); } @Override public long lastDataTime() { - if (omnipodPumpStatus.lastConnection != 0) { - return omnipodPumpStatus.lastConnection; - } - - return System.currentTimeMillis(); + return podStateManager.isPodActivationCompleted() ? podStateManager.getLastSuccessfulCommunication().getMillis() : 0; } @Override public double getBaseBasalRate() { - - if (currentProfile != null) { - int hour = (new GregorianCalendar()).get(Calendar.HOUR_OF_DAY); - return currentProfile.getBasalTimeFromMidnight(DateTimeUtil.getTimeInS(hour * 60)); - } else { + if (!podStateManager.isPodRunning()) { return 0.0d; } + + DateTime now = DateTime.now(); + Duration offset = new Duration(now.withTimeAtStartOfDay(), now); + return podStateManager.getBasalSchedule().rateAt(offset); } @Override public double getReservoirLevel() { - return omnipodPumpStatus.reservoirRemainingUnits; + if (!podStateManager.isPodRunning()) { + return 0.0d; + } + Double reservoirLevel = podStateManager.getReservoirLevel(); + return reservoirLevel == null ? 75.0 : reservoirLevel; } @Override public int getBatteryLevel() { + if (!podStateManager.isPodRunning()) { + return 0; + } return 75; } + @NonNull @Override + public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) { + if (detailedBolusInfo.insulin == 0 && detailedBolusInfo.carbs == 0) { + // neither carbs nor bolus requested + aapsLogger.error("deliverTreatment: Invalid input"); + return new PumpEnactResult(getInjector()).success(false).enacted(false).bolusDelivered(0d).carbsDelivered(0d) + .comment(getResourceHelper().gs(info.nightscout.androidaps.core.R.string.invalidinput)); + } else if (detailedBolusInfo.insulin > 0) { + // bolus needed, ask pump to deliver it + return deliverBolus(detailedBolusInfo); + } else { + // no bolus required, carb only treatment + activePlugin.getActiveTreatments().addToHistoryTreatment(detailedBolusInfo, true); + + // FIXME do we need this?? + EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.INSTANCE; + bolusingEvent.setT(new Treatment()); + bolusingEvent.getT().isSMB = detailedBolusInfo.isSMB; + bolusingEvent.setPercent(100); + rxBus.send(bolusingEvent); + + aapsLogger.debug(LTag.PUMP, "deliverTreatment: Carb only treatment."); + + return new PumpEnactResult(getInjector()).success(true).enacted(true).bolusDelivered(0d) + .carbsDelivered(detailedBolusInfo.carbs).comment(getResourceHelper().gs(info.nightscout.androidaps.core.R.string.common_resultok)); + } + } + @Override - protected void triggerUIChange() { - rxBus.send(new EventOmnipodPumpValuesChanged()); + public void stopBolusDelivering() { + executeCommand(OmnipodCommandType.CANCEL_BOLUS, aapsOmnipodManager::cancelBolus); + } + + // if enforceNew===true current temp basal is cancelled and new TBR set (duration is prolonged), + // if false and the same rate is requested enacted=false and success=true is returned and TBR is not changed + @Override + public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer + durationInMinutes, Profile profile, boolean enforceNew) { + aapsLogger.info(LTag.PUMP, "setTempBasalAbsolute: rate: {}, duration={}", absoluteRate, durationInMinutes); + + // read current TBR + TemporaryBasal tbrCurrent = readTBR(); + + if (tbrCurrent != null) { + aapsLogger.info(LTag.PUMP, "setTempBasalAbsolute: Current Basal: duration: {} min, rate={}", + tbrCurrent.durationInMinutes, tbrCurrent.absoluteRate); + } + + if (tbrCurrent != null && !enforceNew) { + if (Round.isSame(tbrCurrent.absoluteRate, absoluteRate)) { + aapsLogger.info(LTag.PUMP, "setTempBasalAbsolute - No enforceNew and same rate. Exiting."); + rxBus.send(new EventRefreshOverview("Omnipod command: SetTemporaryBasal", false)); + return new PumpEnactResult(getInjector()).success(true).enacted(false); + } + } + + PumpEnactResult result = executeCommand(OmnipodCommandType.SET_TEMPORARY_BASAL, () -> aapsOmnipodManager.setTemporaryBasal(new TempBasalPair(absoluteRate, false, durationInMinutes))); + + aapsLogger.info(LTag.PUMP, "setTempBasalAbsolute - setTBR. Response: " + result.success); + + if (result.success) { + incrementStatistics(OmnipodStorageKeys.Statistics.TBRS_SET); + } + + return result; + } + + @Override + public PumpEnactResult cancelTempBasal(boolean enforceNew) { + TemporaryBasal tbrCurrent = readTBR(); + + if (tbrCurrent == null) { + aapsLogger.info(LTag.PUMP, "cancelTempBasal - TBR already cancelled."); + rxBus.send(new EventRefreshOverview("Omnipod command: CancelTemporaryBasal", false)); + return new PumpEnactResult(getInjector()).success(true).enacted(false); + } + + PumpEnactResult result = executeCommand(OmnipodCommandType.CANCEL_TEMPORARY_BASAL, aapsOmnipodManager::cancelTemporaryBasal); + + if (result.success) { + // TODO is this necessary? + TemporaryBasal tempBasal = new TemporaryBasal(getInjector()) // + .date(System.currentTimeMillis()) // + .duration(0) // + .source(Source.USER); + + activePlugin.getActiveTreatments().addToHistoryTempBasal(tempBasal); + } + + return result; + } + + // TODO improve (i8n and more) + @NonNull @Override + public JSONObject getJSONStatus(Profile profile, String profileName, String version) { + + if (!podStateManager.isPodActivationCompleted() || lastConnectionTimeMillis + 60 * 60 * 1000L < System.currentTimeMillis()) { + return new JSONObject(); + } + + JSONObject pump = new JSONObject(); + JSONObject battery = new JSONObject(); + JSONObject status = new JSONObject(); + JSONObject extended = new JSONObject(); + try { + status.put("status", podStateManager.isPodRunning() ? (podStateManager.isSuspended() ? "suspended" : "normal") : "no active Pod"); + status.put("timestamp", DateUtil.toISOString(new Date())); + + battery.put("percent", getBatteryLevel()); + + extended.put("Version", version); + try { + extended.put("ActiveProfile", profileName); + } catch (Exception ignored) { + } + + TemporaryBasal tb = activePlugin.getActiveTreatments().getRealTempBasalFromHistory(System.currentTimeMillis()); + if (tb != null) { + extended.put("TempBasalAbsoluteRate", + tb.tempBasalConvertedToAbsolute(System.currentTimeMillis(), profile)); + extended.put("TempBasalStart", dateUtil.dateAndTimeString(tb.date)); + extended.put("TempBasalRemaining", tb.getPlannedRemainingMinutes()); + } + + ExtendedBolus eb = activePlugin.getActiveTreatments().getExtendedBolusFromHistory(System.currentTimeMillis()); + if (eb != null) { + extended.put("ExtendedBolusAbsoluteRate", eb.absoluteRate()); + extended.put("ExtendedBolusStart", dateUtil.dateAndTimeString(eb.date)); + extended.put("ExtendedBolusRemaining", eb.getPlannedRemainingMinutes()); + } + + status.put("timestamp", DateUtil.toISOString(new Date())); + + pump.put("battery", battery); + pump.put("status", status); + pump.put("extended", extended); + pump.put("reservoir", getReservoirLevel()); + pump.put("clock", DateUtil.toISOString(new Date())); + } catch (JSONException e) { + aapsLogger.error(LTag.PUMP, "Unhandled exception", e); + } + return pump; + } + + @Override public ManufacturerType manufacturer() { + return pumpType.getManufacturer(); + } + + @Override @NotNull + public PumpType model() { + return pumpType; + } + + @NotNull + @Override + public String serialNumber() { + return podStateManager.isPodInitialized() ? String.valueOf(podStateManager.getAddress()) : "-"; + } + + @Override @NonNull public PumpDescription getPumpDescription() { + return pumpDescription; + } + + // FIXME i18n, null checks: iob, TDD + @NonNull @Override + public String shortStatus(boolean veryShort) { + if (!podStateManager.isPodActivationCompleted()) { + return "No active pod"; + } + String ret = ""; + if (lastConnectionTimeMillis != 0) { + long agoMsec = System.currentTimeMillis() - lastConnectionTimeMillis; + int agoMin = (int) (agoMsec / 60d / 1000d); + ret += "LastConn: " + agoMin + " min ago\n"; + } + if (podStateManager.getLastBolusStartTime() != null) { + ret += "LastBolus: " + DecimalFormatter.to2Decimal(podStateManager.getLastBolusAmount()) + "U @" + // + android.text.format.DateFormat.format("HH:mm", podStateManager.getLastBolusStartTime().toDate()) + "\n"; + } + TemporaryBasal activeTemp = activePlugin.getActiveTreatments().getRealTempBasalFromHistory(System.currentTimeMillis()); + if (activeTemp != null) { + ret += "Temp: " + activeTemp.toStringFull() + "\n"; + } + ExtendedBolus activeExtendedBolus = activePlugin.getActiveTreatments().getExtendedBolusFromHistory( + System.currentTimeMillis()); + if (activeExtendedBolus != null) { + ret += "Extended: " + activeExtendedBolus.toString() + "\n"; + } + ret += "Reserv: " + DecimalFormatter.to0Decimal(getReservoirLevel()) + "U\n"; + ret += "Batt: " + getBatteryLevel(); + return ret; + } + + @Override + public List getCustomActions() { + return customActions; + } + + @Override + public void executeCustomAction(CustomActionType customActionType) { + OmnipodCustomActionType mcat = (OmnipodCustomActionType) customActionType; + + switch (mcat) { + case RESET_RILEY_LINK_CONFIGURATION: + serviceTaskExecutor.startTask(new ResetRileyLinkConfigurationTask(getInjector())); + break; + + default: + aapsLogger.warn(LTag.PUMP, "Unknown custom action: {}" + mcat); + break; + } + } + + @Override + public void timezoneOrDSTChanged(TimeChangeType timeChangeType) { + aapsLogger.warn(LTag.PUMP, "Time, Date and/or TimeZone changed. [changeType=" + timeChangeType.name() + ", eventHandlingEnabled=" + aapsOmnipodManager.isTimeChangeEventEnabled() + "]"); + + if (aapsOmnipodManager.isTimeChangeEventEnabled() && podStateManager.isPodRunning()) { + aapsLogger.info(LTag.PUMP, "Time, Date and/or TimeZone changed event received and will be consumed by driver."); + this.hasTimeDateOrTimeZoneChanged = true; + } + } + + @Override + public boolean isUnreachableAlertTimeoutExceeded(long unreachableTimeoutMilliseconds) { + // We have a separate notification for when no Pod is active, see doPodCheck() + if (podStateManager.isPodActivationCompleted() && podStateManager.getLastSuccessfulCommunication() != null) { // Null check for backwards compatibility + long currentTimeMillis = System.currentTimeMillis(); + + if (podStateManager.getLastSuccessfulCommunication().getMillis() + unreachableTimeoutMilliseconds < currentTimeMillis) { + // We exceeded the user defined alert threshold. However, as we don't send periodical status requests to the Pod to prevent draining it's battery, + // Exceeding the threshold alone is not a reason to trigger an alert: it could very well be that we just didn't need to send any commands for a while + // Below return statement covers these cases in which we will trigger an alert: + // - Sending the last command to the Pod failed + // - The Pod is suspended + // - RileyLink is in an error state + // - RileyLink has been connecting for over RILEY_LINK_CONNECT_TIMEOUT + return (podStateManager.getLastFailedCommunication() != null && podStateManager.getLastSuccessfulCommunication().isBefore(podStateManager.getLastFailedCommunication())) || + podStateManager.isSuspended() || + rileyLinkServiceData.rileyLinkServiceState.isError() || + // The below clause is a hack for working around the RL service state forever staying in connecting state on startup if the RL is switched off / unreachable + (rileyLinkServiceData.getRileyLinkServiceState().isConnecting() && rileyLinkServiceData.getLastServiceStateChange() + RILEY_LINK_CONNECT_TIMEOUT_MILLIS < currentTimeMillis); + } + } + + return false; + } + + public void addPodStatusRequest(OmnipodStatusRequestType pumpStatusRequest) { + statusRequestList.add(pumpStatusRequest); } @Override @@ -598,57 +849,118 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump return false; } - @Override - @NonNull - protected PumpEnactResult deliverBolus(final DetailedBolusInfo detailedBolusInfo) { - aapsLogger.info(LTag.PUMP, getLogPrefix() + "deliverBolus - {}", detailedBolusInfo); - - setRefreshButtonEnabled(false); - - try { - - OmnipodUITask responseTask = getDeviceCommandExecutor().executeCommand(OmnipodCommandType.SetBolus, - detailedBolusInfo); - - PumpEnactResult result = responseTask.getResult(); - - setRefreshButtonEnabled(true); - - if (result.success) { - - // we subtract insulin, exact amount will be visible with next remainingInsulin update. -// if (getPodPumpStatusObject().reservoirRemainingUnits != 0 && -// getPodPumpStatusObject().reservoirRemainingUnits != 75 ) { -// getPodPumpStatusObject().reservoirRemainingUnits -= detailedBolusInfo.insulin; -// } - - incrementStatistics(detailedBolusInfo.isSMB ? OmnipodConst.Statistics.SMBBoluses - : OmnipodConst.Statistics.StandardBoluses); - - result.carbsDelivered(detailedBolusInfo.carbs); - } - - return result; - } finally { - finishAction("Bolus"); - } + @Override public boolean canHandleDST() { + return false; } @Override - public void stopBolusDelivering() { - aapsLogger.info(LTag.PUMP, getLogPrefix() + "stopBolusDelivering"); + public void finishHandshaking() { + if (displayConnectionMessages) + aapsLogger.debug(LTag.PUMP, "finishHandshaking [OmnipodPumpPlugin] - default (empty) implementation."); + } - setRefreshButtonEnabled(false); + @Override public void connect(String reason) { + if (displayConnectionMessages) + aapsLogger.debug(LTag.PUMP, "connect (reason={}) [PumpPluginAbstract] - default (empty) implementation." + reason); + } - OmnipodUITask responseTask = getDeviceCommandExecutor().executeCommand(OmnipodCommandType.CancelBolus); + @Override public void disconnect(String reason) { + if (displayConnectionMessages) + aapsLogger.debug(LTag.PUMP, "disconnect (reason={}) [PumpPluginAbstract] - default (empty) implementation." + reason); + } - PumpEnactResult result = responseTask.getResult(); + @Override public void stopConnecting() { + if (displayConnectionMessages) + aapsLogger.debug(LTag.PUMP, "stopConnecting [PumpPluginAbstract] - default (empty) implementation."); + } - //setRefreshButtonEnabled(true); + @NotNull @Override public PumpEnactResult setTempBasalPercent(Integer percent, Integer + durationInMinutes, Profile profile, boolean enforceNew) { + aapsLogger.debug(LTag.PUMP, "setTempBasalPercent [OmnipodPumpPlugin] - Not implemented."); + return getOperationNotSupportedWithCustomText(info.nightscout.androidaps.core.R.string.pump_operation_not_supported_by_pump_driver); + } - aapsLogger.info(LTag.PUMP, getLogPrefix() + "stopBolusDelivering - wasSuccess={}", result.success); + @NotNull @Override public PumpEnactResult setExtendedBolus(Double insulin, Integer + durationInMinutes) { + aapsLogger.debug(LTag.PUMP, "setExtendedBolus [OmnipodPumpPlugin] - Not implemented."); + return getOperationNotSupportedWithCustomText(info.nightscout.androidaps.core.R.string.pump_operation_not_supported_by_pump_driver); + } - //finishAction("Bolus"); + @NotNull @Override public PumpEnactResult cancelExtendedBolus() { + aapsLogger.debug(LTag.PUMP, "cancelExtendedBolus [OmnipodPumpPlugin] - Not implemented."); + return getOperationNotSupportedWithCustomText(info.nightscout.androidaps.core.R.string.pump_operation_not_supported_by_pump_driver); + } + + @NotNull @Override public PumpEnactResult loadTDDs() { + aapsLogger.debug(LTag.PUMP, "loadTDDs [OmnipodPumpPlugin] - Not implemented."); + return getOperationNotSupportedWithCustomText(info.nightscout.androidaps.core.R.string.pump_operation_not_supported_by_pump_driver); + } + + private void initializeAfterRileyLinkConnection() { + if (podStateManager.isPodInitialized() && podStateManager.getPodProgressStatus().isAtLeast(PodProgressStatus.PAIRING_COMPLETED)) { + PumpEnactResult result = executeCommand(OmnipodCommandType.GET_POD_STATUS, aapsOmnipodManager::getPodStatus); + if (result.success) { + aapsLogger.debug(LTag.PUMP, "Successfully retrieved Pod status on startup"); + } else { + aapsLogger.warn(LTag.PUMP, "Failed to retrieve Pod status on startup"); + } + } else { + aapsLogger.debug(LTag.PUMP, "Not retrieving Pod status on startup: no Pod running"); + } + + if (!sentIdToFirebase) { + Bundle params = new Bundle(); + params.putString("version", BuildConfig.VERSION); + + fabricPrivacy.getFirebaseAnalytics().logEvent("OmnipodPumpInit", params); + + sentIdToFirebase = true; + } + + this.firstRun = false; + } + + @NonNull private PumpEnactResult deliverBolus(final DetailedBolusInfo detailedBolusInfo) { + PumpEnactResult result = executeCommand(OmnipodCommandType.SET_BOLUS, () -> aapsOmnipodManager.bolus(detailedBolusInfo)); + + if (result.success) { + incrementStatistics(detailedBolusInfo.isSMB ? OmnipodStorageKeys.Statistics.SMB_BOLUSES_DELIVERED + : OmnipodStorageKeys.Statistics.STANDARD_BOLUSES_DELIVERED); + + result.carbsDelivered(detailedBolusInfo.carbs); + } + + return result; + } + + private T executeCommand(OmnipodCommandType commandType, Supplier supplier) { + aapsLogger.debug(LTag.PUMP, "Executing command: {}", commandType); + + rileyLinkUtil.getRileyLinkHistory().add(new RLHistoryItemOmnipod(getInjector(), commandType)); + + T pumpEnactResult = supplier.get(); + + rxBus.send(new EventRefreshOverview("Omnipod command: " + commandType.name(), false)); + + rxBus.send(new EventOmnipodPumpValuesChanged()); + + return pumpEnactResult; + } + + private boolean verifyPodAlertConfiguration() { + if (podStateManager.isPodRunning()) { + Duration expirationReminderHoursBeforeShutdown = omnipodAlertUtil.getExpirationReminderTimeBeforeShutdown(); + Integer lowReservoirAlertUnits = omnipodAlertUtil.getLowReservoirAlertUnits(); + + if (!Objects.equals(expirationReminderHoursBeforeShutdown, podStateManager.getExpirationAlertTimeBeforeShutdown()) + || !Objects.equals(lowReservoirAlertUnits, podStateManager.getLowReservoirAlertUnits())) { + aapsLogger.warn(LTag.PUMP, "Configured alerts in Pod don't match AAPS settings: expirationReminderHoursBeforeShutdown = {} (AAPS) vs {} Pod, " + + "lowReservoirAlertUnits = {} (AAPS) vs {} (Pod)", expirationReminderHoursBeforeShutdown, podStateManager.getExpirationAlertTimeBeforeShutdown(), + lowReservoirAlertUnits, podStateManager.getLowReservoirAlertUnits()); + return false; + } + } + return true; } private void incrementStatistics(String statsKey) { @@ -657,215 +969,12 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump sp.putLong(statsKey, currentCount); } - // if enforceNew===true current temp basal is canceled and new TBR set (duration is prolonged), - // if false and the same rate is requested enacted=false and success=true is returned and TBR is not changed - @Override - public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, Profile profile, - boolean enforceNew) { - setRefreshButtonEnabled(false); - - aapsLogger.info(LTag.PUMP, getLogPrefix() + "setTempBasalAbsolute: rate: {}, duration={}", absoluteRate, durationInMinutes); - - // read current TBR - TempBasalPair tbrCurrent = readTBR(); - - if (tbrCurrent != null) { - aapsLogger.info(LTag.PUMP, getLogPrefix() + "setTempBasalAbsolute: Current Basal: duration: {} min, rate={}", - tbrCurrent.getDurationMinutes(), tbrCurrent.getInsulinRate()); - } - - if (tbrCurrent != null && !enforceNew) { - if (Round.isSame(tbrCurrent.getInsulinRate(), absoluteRate)) { - aapsLogger.info(LTag.PUMP, getLogPrefix() + "setTempBasalAbsolute - No enforceNew and same rate. Exiting."); - finishAction("TBR"); - return new PumpEnactResult(getInjector()).success(true).enacted(false); - } - } - - // now start new TBR - OmnipodUITask responseTask = getDeviceCommandExecutor().executeCommand(OmnipodCommandType.SetTemporaryBasal, - absoluteRate, durationInMinutes); - - PumpEnactResult result = responseTask.getResult(); - - aapsLogger.info(LTag.PUMP, getLogPrefix() + "setTempBasalAbsolute - setTBR. Response: " + result.success); - - if (result.success) { - incrementStatistics(OmnipodConst.Statistics.TBRsSet); - } - - finishAction("TBR"); - return result; + private TemporaryBasal readTBR() { + return activePlugin.getActiveTreatments().getTempBasalFromHistory(System.currentTimeMillis()); } - protected TempBasalPair readTBR() { - // TODO we can do it like this or read status from pod ?? - if (omnipodPumpStatus.tempBasalEnd < System.currentTimeMillis()) { - // TBR done - omnipodPumpStatus.clearTemporaryBasal(); - - return null; - } - - return omnipodPumpStatus.getTemporaryBasal(); - } - - protected void finishAction(String overviewKey) { - if (overviewKey != null) - rxBus.send(new EventRefreshOverview(overviewKey, false)); - - triggerUIChange(); - - setRefreshButtonEnabled(true); - } - - @Override - public PumpEnactResult cancelTempBasal(boolean enforceNew) { - - aapsLogger.info(LTag.PUMP, getLogPrefix() + "cancelTempBasal - started"); - - setRefreshButtonEnabled(false); - - TempBasalPair tbrCurrent = readTBR(); - - if (tbrCurrent == null) { - aapsLogger.info(LTag.PUMP, getLogPrefix() + "cancelTempBasal - TBR already canceled."); - finishAction("TBR"); - return new PumpEnactResult(getInjector()).success(true).enacted(false); - } - - OmnipodUITask responseTask2 = getDeviceCommandExecutor().executeCommand(OmnipodCommandType.CancelTemporaryBasal); - - PumpEnactResult result = responseTask2.getResult(); - - finishAction("TBR"); - - if (result.success) { - aapsLogger.info(LTag.PUMP, getLogPrefix() + "cancelTempBasal - Cancel TBR successful."); - - TemporaryBasal tempBasal = new TemporaryBasal() // - .date(System.currentTimeMillis()) // - .duration(0) // - .source(Source.USER); - - activePlugin.getActiveTreatments().addToHistoryTempBasal(tempBasal); - } else { - aapsLogger.info(LTag.PUMP, getLogPrefix() + "cancelTempBasal - Cancel TBR failed."); - } - - return result; - } - - @NotNull - @Override - public String serialNumber() { - return podStateManager.hasPodState() ? String.valueOf(podStateManager.getAddress()) : "None"; - } - - @NotNull - @Override - public PumpEnactResult setNewBasalProfile(Profile profile) { - aapsLogger.info(LTag.PUMP, getLogPrefix() + "setNewBasalProfile"); - - // this shouldn't be needed, but let's do check if profile setting we are setting is same as current one - if (this.currentProfile != null && this.currentProfile.areProfileBasalPatternsSame(profile)) { - return new PumpEnactResult(getInjector()) // - .success(true) // - .enacted(false) // - .comment(resourceHelper.gs(R.string.omnipod_cmd_basal_profile_not_set_is_same)); - } - - setRefreshButtonEnabled(false); - - OmnipodUITask responseTask = getDeviceCommandExecutor().executeCommand(OmnipodCommandType.SetBasalProfile, - profile); - - PumpEnactResult result = responseTask.getResult(); - - aapsLogger.info(LTag.PUMP, getLogPrefix() + "Basal Profile was set: " + result.success); - - if (result.success) { - this.currentProfile = profile; - - Notification notification = new Notification(Notification.PROFILE_SET_OK, - resourceHelper.gs(R.string.profile_set_ok), - Notification.INFO, 60); - rxBus.send(new EventNewNotification(notification)); - } else { - Notification notification = new Notification(Notification.FAILED_UDPATE_PROFILE, - resourceHelper.gs(R.string.failedupdatebasalprofile), - Notification.URGENT); - rxBus.send(new EventNewNotification(notification)); - } - - return result; - } - - // OPERATIONS not supported by Pump or Plugin - - protected List customActions = null; - - private CustomAction customActionResetRLConfig = new CustomAction( - R.string.omnipod_custom_action_reset_rileylink, OmnipodCustomActionType.ResetRileyLinkConfiguration, true); - - - @Override - public List getCustomActions() { - if (customActions == null) { - this.customActions = Arrays.asList( - customActionResetRLConfig //, - ); - } - - return this.customActions; - } - - - @Override - public void executeCustomAction(CustomActionType customActionType) { - OmnipodCustomActionType mcat = (OmnipodCustomActionType) customActionType; - - switch (mcat) { - case ResetRileyLinkConfiguration: { - serviceTaskExecutor.startTask(new ResetRileyLinkConfigurationTask(getInjector())); - } - break; - - default: - break; - } - } - - @Override - public void timezoneOrDSTChanged(TimeChangeType timeChangeType) { - aapsLogger.warn(LTag.PUMP, getLogPrefix() + "Time, Date and/or TimeZone changed. [changeType=" + timeChangeType.name() + ", eventHandlingEnabled=" + omnipodPumpStatus.timeChangeEventEnabled + "]"); - - if (omnipodPumpStatus.timeChangeEventEnabled && podStateManager.isPodRunning()) { - aapsLogger.info(LTag.PUMP, getLogPrefix() + "Time,and/or TimeZone changed event received and will be consumed by driver."); - this.hasTimeDateOrTimeZoneChanged = true; - } - } - - @Override - public boolean isUnreachableAlertTimeoutExceeded(long unreachableTimeoutMilliseconds) { - long rileyLinkInitializationTimeout = 3 * 60 * 1000L; // 3 minutes - if (podStateManager.isPodRunning() && podStateManager.getLastSuccessfulCommunication() != null) { // Null check for backwards compatibility - if (podStateManager.getLastSuccessfulCommunication().getMillis() + unreachableTimeoutMilliseconds < System.currentTimeMillis()) { - if ((podStateManager.getLastFailedCommunication() != null && podStateManager.getLastSuccessfulCommunication().isBefore(podStateManager.getLastFailedCommunication())) || - rileyLinkServiceData.rileyLinkServiceState.isError() || - // The below clause is a hack for working around the RL service state forever staying in connecting state on startup if the RL is switched off / unreachable - (rileyLinkServiceData.getRileyLinkServiceState().isConnecting() && rileyLinkServiceData.getLastServiceStateChange() + rileyLinkInitializationTimeout < System.currentTimeMillis())) { - // We exceeded the alert threshold, and either our last command failed or we cannot reach the RL - // We should show an alert - return true; - } - - // Don't trigger an alert when we exceeded the thresholds, but the last communication was successful & the RL is reachable - // This happens when we simply didn't need to send any commands to the pump - } - } - - return false; + private PumpEnactResult getOperationNotSupportedWithCustomText(int resourceId) { + return new PumpEnactResult(getInjector()).success(false).enacted(false).comment(getResourceHelper().gs(resourceId)); } } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/ConfigureAlertsAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/ConfigureAlertsAction.java deleted file mode 100644 index e5f93e97f3..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/ConfigureAlertsAction.java +++ /dev/null @@ -1,36 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.action; - -import java.util.List; - -import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.ConfigureAlertsCommand; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertConfiguration; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; - -public class ConfigureAlertsAction implements OmnipodAction { - private final PodStateManager podStateManager; - private final List alertConfigurations; - - public ConfigureAlertsAction(PodStateManager podStateManager, List alertConfigurations) { - if (podStateManager == null) { - throw new ActionInitializationException("Pod state manager cannot be null"); - } - if (alertConfigurations == null) { - throw new ActionInitializationException("Alert configurations cannot be null"); - } - this.podStateManager = podStateManager; - this.alertConfigurations = alertConfigurations; - } - - @Override - public StatusResponse execute(OmnipodCommunicationManager communicationService) { - ConfigureAlertsCommand configureAlertsCommand = new ConfigureAlertsCommand(podStateManager.getCurrentNonce(), alertConfigurations); - StatusResponse statusResponse = communicationService.sendCommand(StatusResponse.class, podStateManager, configureAlertsCommand); - for (AlertConfiguration alertConfiguration : alertConfigurations) { - podStateManager.putConfiguredAlert(alertConfiguration.getAlertSlot(), alertConfiguration.getAlertType()); - } - return statusResponse; - } -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/GetPodInfoAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/GetPodInfoAction.java deleted file mode 100644 index a082ca47d8..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/GetPodInfoAction.java +++ /dev/null @@ -1,29 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.action; - -import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.GetStatusCommand; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; - -public class GetPodInfoAction implements OmnipodAction { - private final PodStateManager podStateManager; - private final PodInfoType podInfoType; - - public GetPodInfoAction(PodStateManager podStateManager, PodInfoType podInfoType) { - if (podStateManager == null) { - throw new ActionInitializationException("Pod state manager cannot be null"); - } - if (podInfoType == null) { - throw new ActionInitializationException("Pod info type cannot be null"); - } - this.podStateManager = podStateManager; - this.podInfoType = podInfoType; - } - - @Override - public PodInfoResponse execute(OmnipodCommunicationManager communicationService) { - return communicationService.sendCommand(PodInfoResponse.class, podStateManager, new GetStatusCommand(podInfoType)); - } -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/GetStatusAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/GetStatusAction.java deleted file mode 100644 index 6cad5798a2..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/GetStatusAction.java +++ /dev/null @@ -1,24 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.action; - -import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.GetStatusCommand; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; - -public class GetStatusAction implements OmnipodAction { - private final PodStateManager podStateManager; - - public GetStatusAction(PodStateManager podState) { - if (podState == null) { - throw new ActionInitializationException("Pod state manager cannot be null"); - } - this.podStateManager = podState; - } - - @Override - public StatusResponse execute(OmnipodCommunicationManager communicationService) { - return communicationService.sendCommand(StatusResponse.class, podStateManager, new GetStatusCommand(PodInfoType.NORMAL)); - } -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/InsertCannulaAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/InsertCannulaAction.java deleted file mode 100644 index 53c0e2a4a8..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/InsertCannulaAction.java +++ /dev/null @@ -1,55 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.action; - -import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.service.InsertCannulaService; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalPodProgressException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodProgressStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BasalSchedule; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; - -public class InsertCannulaAction implements OmnipodAction { - - private final PodStateManager podStateManager; - private final InsertCannulaService service; - private final BasalSchedule initialBasalSchedule; - - public InsertCannulaAction(InsertCannulaService insertCannulaService, PodStateManager podStateManager, BasalSchedule initialBasalSchedule) { - if (insertCannulaService == null) { - throw new ActionInitializationException("Insert cannula service cannot be null"); - } - if (podStateManager == null) { - throw new ActionInitializationException("Pod state manager cannot be null"); - } - if (initialBasalSchedule == null) { - throw new ActionInitializationException("Initial basal schedule cannot be null"); - } - this.service = insertCannulaService; - this.podStateManager = podStateManager; - this.initialBasalSchedule = initialBasalSchedule; - } - - @Override - public StatusResponse execute(OmnipodCommunicationManager communicationService) { - if (!podStateManager.isPodInitialized() || podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.PRIMING_COMPLETED)) { - throw new IllegalPodProgressException(PodProgressStatus.PRIMING_COMPLETED, podStateManager.isPodInitialized() ? podStateManager.getPodProgressStatus() : null); - } - - if (podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.BASAL_INITIALIZED)) { - service.programInitialBasalSchedule(communicationService, podStateManager, initialBasalSchedule); - } - if (podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.INSERTING_CANNULA)) { - } - - if (podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.INSERTING_CANNULA)) { - service.executeExpirationRemindersAlertCommand(communicationService, podStateManager); - return service.executeInsertionBolusCommand(communicationService, podStateManager); - } else if (podStateManager.getPodProgressStatus().equals(PodProgressStatus.INSERTING_CANNULA)) { - // Check status - return communicationService.executeAction(new GetStatusAction(podStateManager)); - } else { - throw new IllegalPodProgressException(null, podStateManager.getPodProgressStatus()); - } - } -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/OmnipodAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/OmnipodAction.java deleted file mode 100644 index f561a276d4..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/OmnipodAction.java +++ /dev/null @@ -1,7 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.action; - -import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; - -public interface OmnipodAction { - T execute(OmnipodCommunicationManager communicationService); -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/service/InsertCannulaService.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/service/InsertCannulaService.java deleted file mode 100644 index e8add2e9f7..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/service/InsertCannulaService.java +++ /dev/null @@ -1,59 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.action.service; - -import org.joda.time.DateTime; -import org.joda.time.Duration; - -import java.util.Arrays; -import java.util.List; - -import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.BolusAction; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.ConfigureAlertsAction; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.SetBasalScheduleAction; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertConfiguration; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertConfigurationFactory; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BasalSchedule; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; - -public class InsertCannulaService { - public StatusResponse programInitialBasalSchedule(OmnipodCommunicationManager communicationService, - PodStateManager podStateManager, BasalSchedule basalSchedule) { - return communicationService.executeAction(new SetBasalScheduleAction(podStateManager, basalSchedule, - true, podStateManager.getScheduleOffset(), false)); - } - - public StatusResponse executeExpirationRemindersAlertCommand(OmnipodCommunicationManager communicationService, - PodStateManager podStateManager) { - AlertConfiguration lowReservoirAlertConfiguration = AlertConfigurationFactory.createLowReservoirAlertConfiguration(OmnipodConst.LOW_RESERVOIR_ALERT); - - DateTime endOfServiceTime = podStateManager.getActivatedAt().plus(OmnipodConst.SERVICE_DURATION); - - Duration timeUntilExpirationAdvisoryAlarm = new Duration(DateTime.now(), - endOfServiceTime.minus(OmnipodConst.EXPIRATION_ADVISORY_WINDOW)); - Duration timeUntilShutdownImminentAlarm = new Duration(DateTime.now(), - endOfServiceTime.minus(OmnipodConst.END_OF_SERVICE_IMMINENT_WINDOW)); - - AlertConfiguration expirationAdvisoryAlertConfiguration = AlertConfigurationFactory.createExpirationAdvisoryAlertConfiguration( - timeUntilExpirationAdvisoryAlarm, OmnipodConst.EXPIRATION_ADVISORY_WINDOW); - AlertConfiguration shutdownImminentAlertConfiguration = AlertConfigurationFactory.createShutdownImminentAlertConfiguration( - timeUntilShutdownImminentAlarm); - AlertConfiguration autoOffAlertConfiguration = AlertConfigurationFactory.createAutoOffAlertConfiguration( - false, Duration.ZERO); - - List alertConfigurations = Arrays.asList( // - lowReservoirAlertConfiguration, // - expirationAdvisoryAlertConfiguration, // - shutdownImminentAlertConfiguration, // - autoOffAlertConfiguration // - ); - - return communicationService.executeAction(new ConfigureAlertsAction(podStateManager, alertConfigurations)); - } - - public StatusResponse executeInsertionBolusCommand(OmnipodCommunicationManager communicationService, PodStateManager podStateManager) { - return communicationService.executeAction(new BolusAction(podStateManager, OmnipodConst.POD_CANNULA_INSERTION_BOLUS_UNITS, - Duration.standardSeconds(1), false, false)); - } -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/service/PrimeService.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/service/PrimeService.java deleted file mode 100644 index d8726be029..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/service/PrimeService.java +++ /dev/null @@ -1,37 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.action.service; - -import org.joda.time.Duration; - -import java.util.Collections; - -import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.BolusAction; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.ConfigureAlertsAction; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.OmnipodMessage; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.FaultConfigCommand; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertConfiguration; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertConfigurationFactory; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; - -public class PrimeService { - - public StatusResponse executeDisableTab5Sub16FaultConfigCommand(OmnipodCommunicationManager communicationService, PodStateManager podStateManager) { - FaultConfigCommand faultConfigCommand = new FaultConfigCommand(podStateManager.getCurrentNonce(), (byte) 0x00, (byte) 0x00); - OmnipodMessage faultConfigMessage = new OmnipodMessage(podStateManager.getAddress(), - Collections.singletonList(faultConfigCommand), podStateManager.getMessageNumber()); - return communicationService.exchangeMessages(StatusResponse.class, podStateManager, faultConfigMessage); - } - - public StatusResponse executeFinishSetupReminderAlertCommand(OmnipodCommunicationManager communicationService, PodStateManager podStateManager) { - AlertConfiguration finishSetupReminderAlertConfiguration = AlertConfigurationFactory.createFinishSetupReminderAlertConfiguration(); - return communicationService.executeAction(new ConfigureAlertsAction(podStateManager, - Collections.singletonList(finishSetupReminderAlertConfiguration))); - } - - public StatusResponse executePrimeBolusCommand(OmnipodCommunicationManager communicationService, PodStateManager podStateManager) { - return communicationService.executeAction(new BolusAction(podStateManager, OmnipodConst.POD_PRIME_BOLUS_UNITS, - Duration.standardSeconds(1), false, false)); - } -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/NonceOutOfSyncException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/NonceOutOfSyncException.java deleted file mode 100644 index 929afbb855..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/NonceOutOfSyncException.java +++ /dev/null @@ -1,9 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.exception; - -import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException; - -public class NonceOutOfSyncException extends OmnipodException { - public NonceOutOfSyncException() { - super("Nonce out of sync", true); - } -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/NonceResyncException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/NonceResyncException.java deleted file mode 100644 index a4910c9a42..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/NonceResyncException.java +++ /dev/null @@ -1,9 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.exception; - -import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException; - -public class NonceResyncException extends OmnipodException { - public NonceResyncException() { - super("Nonce resync failed", true); - } -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/IRawRepresentable.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/IRawRepresentable.java deleted file mode 100644 index 2eec2afaf8..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/IRawRepresentable.java +++ /dev/null @@ -1,5 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message; - -public interface IRawRepresentable { - byte[] getRawData(); -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dagger/OmnipodModule.kt b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dagger/OmnipodModule.kt new file mode 100644 index 0000000000..770de8d277 --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dagger/OmnipodModule.kt @@ -0,0 +1,50 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dagger + +import dagger.Module +import dagger.Provides +import dagger.android.ContributesAndroidInjector +import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodPumpPlugin +import info.nightscout.androidaps.plugins.pump.omnipod.data.RLHistoryItemOmnipod +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager +import info.nightscout.androidaps.plugins.pump.omnipod.manager.AapsOmnipodManager +import info.nightscout.androidaps.plugins.pump.omnipod.manager.AapsPodStateManager +import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager +import info.nightscout.androidaps.plugins.pump.omnipod.ui.PodHistoryActivity +import info.nightscout.androidaps.plugins.pump.omnipod.ui.PodManagementActivity +import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.initpod.InitActionFragment +import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.initpod.InitPodTask +import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.pages.InitPodRefreshAction +import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.pages.PodInfoFragment +import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.removepod.RemoveActionFragment + +@Module +@Suppress("unused") +abstract class OmnipodModule { + + // Activities + @ContributesAndroidInjector + abstract fun contributesPodManagementActivity(): PodManagementActivity + @ContributesAndroidInjector abstract fun contributesPodHistoryActivity(): PodHistoryActivity + + // Fragments + @ContributesAndroidInjector abstract fun initActionFragment(): InitActionFragment + @ContributesAndroidInjector abstract fun removeActionFragment(): RemoveActionFragment + @ContributesAndroidInjector abstract fun podInfoFragment(): PodInfoFragment + + // Service + @ContributesAndroidInjector + abstract fun omnipodCommunicationManagerProvider(): OmnipodRileyLinkCommunicationManager + @ContributesAndroidInjector abstract fun aapsOmnipodManagerProvider(): AapsOmnipodManager + + // Data + @ContributesAndroidInjector abstract fun initPodRefreshAction(): InitPodRefreshAction + @ContributesAndroidInjector abstract fun podStateManager(): PodStateManager + @ContributesAndroidInjector abstract fun initPodTask(): InitPodTask + @ContributesAndroidInjector abstract fun omnipodPumpPlugin(): OmnipodPumpPlugin + @ContributesAndroidInjector abstract fun rlHistoryItemOmnipod(): RLHistoryItemOmnipod + + companion object { + @Provides + fun podStateManagerProvider(aapsPodStateManager: AapsPodStateManager): PodStateManager = aapsPodStateManager + } +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/data/RLHistoryItemOmnipod.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/data/RLHistoryItemOmnipod.java index ace31f26d8..fee331d4ac 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/data/RLHistoryItemOmnipod.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/data/RLHistoryItemOmnipod.java @@ -2,24 +2,29 @@ package info.nightscout.androidaps.plugins.pump.omnipod.data; import org.joda.time.LocalDateTime; +import javax.inject.Inject; + +import dagger.android.HasAndroidInjector; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.data.RLHistoryItem; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodCommandType; +import info.nightscout.androidaps.plugins.pump.omnipod.definition.OmnipodCommandType; import info.nightscout.androidaps.utils.resources.ResourceHelper; public class RLHistoryItemOmnipod extends RLHistoryItem { - private OmnipodCommandType omnipodCommandType; + @Inject ResourceHelper resourceHelper; + private final OmnipodCommandType omnipodCommandType; - public RLHistoryItemOmnipod(OmnipodCommandType omnipodCommandType) { + public RLHistoryItemOmnipod(HasAndroidInjector injector, OmnipodCommandType omnipodCommandType) { super(new LocalDateTime(), RLHistoryItemSource.OmnipodCommand, RileyLinkTargetDevice.Omnipod); + injector.androidInjector().inject(this); this.omnipodCommandType = omnipodCommandType; } @Override public String getDescription(ResourceHelper resourceHelper) { if (RLHistoryItemSource.OmnipodCommand.equals(source)) { - return omnipodCommandType.name(); + return resourceHelper.gs(omnipodCommandType.getResourceId()); } return super.getDescription(resourceHelper); } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/definition/OmnipodCommandType.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/definition/OmnipodCommandType.java new file mode 100644 index 0000000000..b7be57c864 --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/definition/OmnipodCommandType.java @@ -0,0 +1,34 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.definition; + +import info.nightscout.androidaps.plugins.pump.omnipod.R; + +/** + * Created by andy on 4.8.2019 + */ +public enum OmnipodCommandType { + PAIR_AND_PRIME_POD(R.string.omnipod_cmd_pair_and_prime), // First step of Pod activation + FILL_CANNULA_AND_SET_BASAL_PROFILE(R.string.omnipod_cmd_fill_cannula_set_basal_profile), // Second step of Pod activation + DEACTIVATE_POD(R.string.omnipod_cmd_deactivate_pod), // + SET_BASAL_PROFILE(R.string.omnipod_cmd_set_basal_schedule), // + SET_BOLUS(R.string.omnipod_cmd_set_bolus), // + CANCEL_BOLUS(R.string.omnipod_cmd_cancel_bolus), // + SET_TEMPORARY_BASAL(R.string.omnipod_cmd_set_tbr), // + CANCEL_TEMPORARY_BASAL(R.string.omnipod_cmd_cancel_tbr_by_driver), // + DISCARD_POD(R.string.omnipod_cmd_discard_pod), // + GET_POD_STATUS(R.string.omnipod_cmd_get_pod_status), // + SET_TIME(R.string.omnipod_cmd_set_time), // + CONFIGURE_ALERTS(R.string.omnipod_cmd_configure_alerts), // + ACKNOWLEDGE_ALERTS(R.string.omnipod_cmd_acknowledge_alerts), // + GET_POD_PULSE_LOG(R.string.omnipod_cmd_get_pulse_log), // + SUSPEND_DELIVERY(R.string.omnipod_cmd_suspend_delivery); + + private int resourceId; + + OmnipodCommandType(int resourceId) { + this.resourceId = resourceId; + } + + public int getResourceId() { + return resourceId; + } +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/OmnipodCustomActionType.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/definition/OmnipodCustomActionType.java similarity index 53% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/OmnipodCustomActionType.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/definition/OmnipodCustomActionType.java index edf7181f18..9d9fbf3f13 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/OmnipodCustomActionType.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/definition/OmnipodCustomActionType.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; +package info.nightscout.androidaps.plugins.pump.omnipod.definition; import info.nightscout.androidaps.plugins.general.actions.defs.CustomActionType; @@ -7,14 +7,7 @@ import info.nightscout.androidaps.plugins.general.actions.defs.CustomActionType; */ public enum OmnipodCustomActionType implements CustomActionType { - - ResetRileyLinkConfiguration(), // - PairAndPrime(), // - FillCanulaSetBasalProfile(), // - //InitPod(), // - DeactivatePod(), // - ResetPodStatus(), // - ; + RESET_RILEY_LINK_CONFIGURATION; @Override public String getKey() { diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/definition/OmnipodStatusRequestType.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/definition/OmnipodStatusRequestType.java new file mode 100644 index 0000000000..c657f6fc6e --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/definition/OmnipodStatusRequestType.java @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.definition; + +public enum OmnipodStatusRequestType { + ACKNOWLEDGE_ALERTS, + GET_POD_STATE, + GET_PULSE_LOG, + SUSPEND_DELIVERY +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/definition/OmnipodStorageKeys.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/definition/OmnipodStorageKeys.java new file mode 100644 index 0000000000..272325ea90 --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/definition/OmnipodStorageKeys.java @@ -0,0 +1,29 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.definition; + +import info.nightscout.androidaps.plugins.pump.omnipod.R; + +public class OmnipodStorageKeys { + private static final String PREFIX = "AAPS.Omnipod."; + + public static class Preferences { + public static final String POD_STATE = PREFIX + "pod_state"; + public static final String ACTIVE_BOLUS = PREFIX + "current_bolus"; + public static final int BASAL_BEEPS_ENABLED = R.string.key_omnipod_basal_beeps_enabled; + public static final int BOLUS_BEEPS_ENABLED = R.string.key_omnipod_bolus_beeps_enabled; + public static final int SMB_BEEPS_ENABLED = R.string.key_omnipod_smb_beeps_enabled; + public static final int TBR_BEEPS_ENABLED = R.string.key_omnipod_tbr_beeps_enabled; + public static final int SUSPEND_DELIVERY_BUTTON_ENABLED = R.string.key_omnipod_pulse_log_button_enabled; + public static final int PULSE_LOG_BUTTON_ENABLED = R.string.key_omnipod_pulse_log_button_enabled; + public static final int TIME_CHANGE_EVENT_ENABLED = R.string.key_omnipod_time_change_event_enabled; + public static final int EXPIRATION_REMINDER_ENABLED = R.string.key_omnipod_expiration_reminder_enabled; + public static final int EXPIRATION_REMINDER_HOURS_BEFORE_SHUTDOWN = R.string.key_omnipod_expiration_reminder_hours_before_shutdown; + public static final int LOW_RESERVOIR_ALERT_ENABLED = R.string.key_omnipod_low_reservoir_alert_enabled; + public static final int LOW_RESERVOIR_ALERT_UNITS = R.string.key_omnipod_low_reservoir_alert_units; + } + + public static class Statistics { + public static final String TBRS_SET = PREFIX + "tbrs_set"; + public static final String STANDARD_BOLUSES_DELIVERED = PREFIX + "std_boluses_delivered"; + public static final String SMB_BOLUSES_DELIVERED = PREFIX + "smb_boluses_delivered"; + } +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/definition/PodHistoryEntryType.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/definition/PodHistoryEntryType.java new file mode 100644 index 0000000000..cd15bac1a4 --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/definition/PodHistoryEntryType.java @@ -0,0 +1,94 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.definition; + +import androidx.annotation.StringRes; + +import java.util.HashMap; +import java.util.Map; + +import info.nightscout.androidaps.plugins.pump.common.defs.PumpHistoryEntryGroup; +import info.nightscout.androidaps.plugins.pump.omnipod.R; + +/** + * Created by andy on 24.11.2019 + */ +public enum PodHistoryEntryType { + + PAIR_AND_PRIME(1, R.string.omnipod_init_pod_wizard_step2_title, PumpHistoryEntryGroup.Prime), + FILL_CANNULA_SET_BASAL_PROFILE(2, R.string.omnipod_init_pod_wizard_step4_title, PumpHistoryEntryGroup.Prime), + DEACTIVATE_POD(3, R.string.omnipod_cmd_deactivate_pod, PumpHistoryEntryGroup.Prime), + RESET_POD_STATE(4, R.string.omnipod_cmd_discard_pod, PumpHistoryEntryGroup.Prime), + + SET_TEMPORARY_BASAL(10, R.string.omnipod_cmd_set_tbr, PumpHistoryEntryGroup.Basal), + CANCEL_TEMPORARY_BASAL_BY_DRIVER(11, R.string.omnipod_cmd_cancel_tbr_by_driver, PumpHistoryEntryGroup.Basal), + CANCEL_TEMPORARY_BASAL(12, R.string.omnipod_cmd_cancel_tbr, PumpHistoryEntryGroup.Basal), + SET_FAKE_SUSPENDED_TEMPORARY_BASAL(13, R.string.omnipod_cmd_set_fake_suspended_tbr, PumpHistoryEntryGroup.Basal), + CANCEL_FAKE_SUSPENDED_TEMPORARY_BASAL(14, R.string.omnipod_cmd_cancel_fake_suspended_tbr, PumpHistoryEntryGroup.Basal), + + SET_BASAL_SCHEDULE(20, R.string.omnipod_cmd_set_basal_schedule, PumpHistoryEntryGroup.Basal), + + GET_POD_STATUS(30, R.string.omnipod_cmd_get_pod_status, PumpHistoryEntryGroup.Configuration), + GET_POD_INFO(31, R.string.omnipod_cmd_get_pod_info, PumpHistoryEntryGroup.Configuration), + SET_TIME(32, R.string.omnipod_cmd_set_time, PumpHistoryEntryGroup.Configuration), + + SET_BOLUS(40, R.string.omnipod_cmd_set_bolus, PumpHistoryEntryGroup.Bolus), + CANCEL_BOLUS(41, R.string.omnipod_cmd_cancel_bolus, PumpHistoryEntryGroup.Bolus), + + CONFIGURE_ALERTS(50, R.string.omnipod_cmd_configure_alerts, PumpHistoryEntryGroup.Alarm), + ACKNOWLEDGE_ALERTS(51, R.string.omnipod_cmd_acknowledge_alerts, PumpHistoryEntryGroup.Alarm), + + SUSPEND_DELIVERY(60, R.string.omnipod_cmd_suspend_delivery, PumpHistoryEntryGroup.Basal), + RESUME_DELIVERY(61, R.string.omnipod_cmd_resume_delivery, PumpHistoryEntryGroup.Basal), + + UNKNOWN_ENTRY_TYPE(99, R.string.omnipod_cmd_unknown_entry); + + private int code; + private static final Map instanceMap; + + @StringRes + private int resourceId; + + private PumpHistoryEntryGroup group; + + static { + instanceMap = new HashMap<>(); + + for (PodHistoryEntryType value : values()) { + instanceMap.put(value.code, value); + } + } + + PodHistoryEntryType(int code, @StringRes int resourceId) { + this.code = code; + this.resourceId = resourceId; + } + + PodHistoryEntryType(int code, @StringRes int resourceId, PumpHistoryEntryGroup group) { + this.code = code; + this.resourceId = resourceId; + this.group = group; + } + + public int getCode() { + return code; + } + + public PumpHistoryEntryGroup getGroup() { + return this.group; + } + + public static PodHistoryEntryType getByCode(long code) { + return getByCode((int) code); + } + + public static PodHistoryEntryType getByCode(int code) { + if (instanceMap.containsKey(code)) { + return instanceMap.get(code); + } else { + return UNKNOWN_ENTRY_TYPE; + } + } + + public int getResourceId() { + return resourceId; + } +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/PodInitActionType.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/definition/PodInitActionType.java similarity index 51% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/PodInitActionType.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/definition/PodInitActionType.java index 1e614ee779..1424712010 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/PodInitActionType.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/definition/PodInitActionType.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; +package info.nightscout.androidaps.plugins.pump.omnipod.definition; import java.util.ArrayList; import java.util.List; @@ -7,17 +7,17 @@ import info.nightscout.androidaps.plugins.pump.omnipod.R; public enum PodInitActionType { - PairAndPrimeWizardStep(), // - PairPod(R.string.omnipod_init_pod_pair_pod, PairAndPrimeWizardStep), // - PrimePod(R.string.omnipod_init_pod_prime_pod, PairAndPrimeWizardStep), // + PAIR_AND_PRIME_WIZARD_STEP(), // + PAIR_POD(R.string.omnipod_init_pod_pair_pod, PAIR_AND_PRIME_WIZARD_STEP), // + PRIME_POD(R.string.omnipod_init_pod_prime_pod, PAIR_AND_PRIME_WIZARD_STEP), // - FillCannulaSetBasalProfileWizardStep(), // - FillCannula(R.string.omnipod_init_pod_fill_cannula, FillCannulaSetBasalProfileWizardStep), // - SetBasalProfile(R.string.omnipod_init_pod_set_basal_profile, FillCannulaSetBasalProfileWizardStep), // + FILL_CANNULA_SET_BASAL_PROFILE_WIZARD_STEP(), // + FILL_CANNULA(R.string.omnipod_init_pod_fill_cannula, FILL_CANNULA_SET_BASAL_PROFILE_WIZARD_STEP), // + SET_BASAL_PROFILE(R.string.omnipod_init_pod_set_basal_profile, FILL_CANNULA_SET_BASAL_PROFILE_WIZARD_STEP), // - DeactivatePodWizardStep(), // - CancelDelivery(R.string.omnipod_deactivate_pod_cancel_delivery, DeactivatePodWizardStep), // - DeactivatePod(R.string.omnipod_deactivate_pod_deactivate_pod, DeactivatePodWizardStep); + DEACTIVATE_POD_WIZARD_STEP(), // + CANCEL_DELIVERY(R.string.omnipod_deactivate_pod_cancel_delivery, DEACTIVATE_POD_WIZARD_STEP), // + DEACTIVATE_POD(R.string.omnipod_deactivate_pod_deactivate_pod, DEACTIVATE_POD_WIZARD_STEP); private int resourceId; private PodInitActionType parent; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/PodInitReceiver.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/definition/PodInitReceiver.java similarity index 68% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/PodInitReceiver.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/definition/PodInitReceiver.java index 789da1add2..35f9f41229 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/PodInitReceiver.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/definition/PodInitReceiver.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; +package info.nightscout.androidaps.plugins.pump.omnipod.definition; public interface PodInitReceiver { diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/AlertTrigger.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/AlertTrigger.java deleted file mode 100644 index 1dedb458d0..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/AlertTrigger.java +++ /dev/null @@ -1,14 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; - -public abstract class AlertTrigger { - protected T value; - - public AlertTrigger(T value) { - this.value = value; - } - - public T getValue() { - return value; - } -} - diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/IOmnipodManager.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/IOmnipodManager.java deleted file mode 100644 index 649154f655..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/IOmnipodManager.java +++ /dev/null @@ -1,74 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; - -import info.nightscout.androidaps.data.DetailedBolusInfo; -import info.nightscout.androidaps.data.Profile; -import info.nightscout.androidaps.data.PumpEnactResult; -import info.nightscout.androidaps.plugins.pump.common.data.TempBasalPair; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoRecentPulseLog; - -// TODO remove? -// We only have this interface for possible Omnipod Dash implementation -public interface IOmnipodManager { - - /** - * Initialize Pod - */ - PumpEnactResult initPod(PodInitActionType podInitActionType, PodInitReceiver podInitReceiver, Profile profile); - - /** - * Get Pod Status (is pod running, battery left ?, reservoir, etc) - */ - // TODO we should probably return a (wrapped) StatusResponse instead of a PumpEnactResult - PumpEnactResult getPodStatus(); - - /** - * Deactivate Pod - */ - PumpEnactResult deactivatePod(PodInitReceiver podInitReceiver); - - /** - * Set Basal Profile - */ - PumpEnactResult setBasalProfile(Profile basalProfile); - - /** - * Reset Pod status (if we forget to disconnect Pod and want to init new pod, and want to forget current pod) - */ - PumpEnactResult resetPodStatus(); - - /** - * Set Bolus - * - * @param detailedBolusInfo DetailedBolusInfo instance with amount and all other required data - */ - PumpEnactResult setBolus(DetailedBolusInfo detailedBolusInfo); - - /** - * Cancel Bolus (if bolus is already stopped, return acknowledgment) - */ - PumpEnactResult cancelBolus(); - - /** - * Set Temporary Basal - * - * @param tempBasalPair TempBasalPair object containg amount and duration in minutes - */ - PumpEnactResult setTemporaryBasal(TempBasalPair tempBasalPair); - - /** - * Cancel Temporary Basal (if TB is already stopped, return acknowledgment) - */ - PumpEnactResult cancelTemporaryBasal(); - - /** - * Acknowledge alerts - */ - PumpEnactResult acknowledgeAlerts(); - - /** - * Set Time on Pod - */ - PumpEnactResult setTime(); - - PodInfoRecentPulseLog readPulseLog(); -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/NonceState.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/NonceState.java deleted file mode 100644 index 4698f88266..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/NonceState.java +++ /dev/null @@ -1,53 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; - -import java.util.Arrays; - -public class NonceState { - private final long[] table = new long[21]; - private int index; - - public NonceState(int lot, int tid) { - initializeTable(lot, tid, (byte) 0x00); - } - - public NonceState(int lot, int tid, byte seed) { - initializeTable(lot, tid, seed); - } - - private void initializeTable(int lot, int tid, byte seed) { - table[0] = (long) (lot & 0xFFFF) + 0x55543DC3L + (((long) (lot) & 0xFFFFFFFFL) >> 16); - table[0] = table[0] & 0xFFFFFFFFL; - table[1] = (tid & 0xFFFF) + 0xAAAAE44EL + (((long) (tid) & 0xFFFFFFFFL) >> 16); - table[1] = table[1] & 0xFFFFFFFFL; - index = 0; - table[0] += seed; - for (int i = 0; i < 16; i++) { - table[2 + i] = generateEntry(); - } - index = (int) ((table[0] + table[1]) & 0X0F); - } - - private int generateEntry() { - table[0] = (((table[0] >> 16) + (table[0] & 0xFFFF) * 0x5D7FL) & 0xFFFFFFFFL); - table[1] = (((table[1] >> 16) + (table[1] & 0xFFFF) * 0x8CA0L) & 0xFFFFFFFFL); - return (int) ((table[1] + (table[0] << 16)) & 0xFFFFFFFFL); - } - - public int getCurrentNonce() { - return (int) table[(2 + index)]; - } - - public void advanceToNextNonce() { - int nonce = getCurrentNonce(); - table[(2 + index)] = generateEntry(); - index = (nonce & 0x0F); - } - - @Override - public String toString() { - return "NonceState{" + - "table=" + Arrays.toString(table) + - ", index=" + index + - '}'; - } -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/OmnipodCommandType.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/OmnipodCommandType.java deleted file mode 100644 index bb0d40ef59..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/OmnipodCommandType.java +++ /dev/null @@ -1,24 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; - -/** - * Created by andy on 4.8.2019 - */ -public enum OmnipodCommandType { - - PairAndPrimePod, // - FillCanulaAndSetBasalProfile, // - //InitPod, // - DeactivatePod, // - SetBasalProfile, // - SetBolus, // - CancelBolus, // - SetTemporaryBasal, // - CancelTemporaryBasal, // - ResetPodStatus, // - GetPodStatus, // - SetTime, // - AcknowledgeAlerts, // - GetPodPulseLog; - - -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/OmnipodPumpPluginInterface.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/OmnipodPumpPluginInterface.java deleted file mode 100644 index 50cfec2d88..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/OmnipodPumpPluginInterface.java +++ /dev/null @@ -1,9 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; - -import info.nightscout.androidaps.interfaces.PumpInterface; - -public interface OmnipodPumpPluginInterface extends PumpInterface { - - void addPodStatusRequest(OmnipodStatusRequest pumpStatusRequest); - -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/OmnipodStatusRequest.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/OmnipodStatusRequest.java deleted file mode 100644 index 2ab1ca024f..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/OmnipodStatusRequest.java +++ /dev/null @@ -1,19 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; - -public enum OmnipodStatusRequest { - ResetState(OmnipodCommandType.ResetPodStatus), // - AcknowledgeAlerts(OmnipodCommandType.AcknowledgeAlerts), // - GetPodState(OmnipodCommandType.GetPodStatus), // - GetPodPulseLog(OmnipodCommandType.GetPodPulseLog); - - private OmnipodCommandType commandType; - - OmnipodStatusRequest(OmnipodCommandType commandType) { - this.commandType = commandType; - } - - - public OmnipodCommandType getCommandType() { - return commandType; - } -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/OmnipodUIResponseType.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/OmnipodUIResponseType.java deleted file mode 100644 index b135c3f590..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/OmnipodUIResponseType.java +++ /dev/null @@ -1,13 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; - -/** - * Created by andy on 10/18/18. - */ - -public enum OmnipodUIResponseType { - - Data, - Error, - Invalid; - -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/PodResponseType.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/PodResponseType.java deleted file mode 100644 index ef65ae8d96..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/PodResponseType.java +++ /dev/null @@ -1,13 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; - -public enum PodResponseType { - - Acknowledgment, // set commands would just acknowledge if data was sent - Data, // query commands would return data - Error, // communication/response produced an error - Invalid; // invalid response (not supported, should never be returned) - - public boolean isError() { - return this == Error || this == Invalid; - } -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/DeliverySchedule.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/DeliverySchedule.java deleted file mode 100644 index 325b7f19e4..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/DeliverySchedule.java +++ /dev/null @@ -1,10 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule; - -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.IRawRepresentable; - -public abstract class DeliverySchedule implements IRawRepresentable { - - public abstract InsulinScheduleType getType(); - - public abstract int getChecksum(); -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/defs/PodActionType.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/defs/PodActionType.java deleted file mode 100644 index 674703855a..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/defs/PodActionType.java +++ /dev/null @@ -1,7 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.defs; - -public enum PodActionType { - InitPod, - RemovePod, - ResetPod -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/model/InitPodWizardModel.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/model/InitPodWizardModel.java deleted file mode 100644 index 405b4dd063..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/model/InitPodWizardModel.java +++ /dev/null @@ -1,20 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.model; - -import android.content.Context; - -import androidx.fragment.app.Fragment; - -import com.tech.freak.wizardpager.model.AbstractWizardModel; - -import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.pages.PodInfoFragment; - -public abstract class InitPodWizardModel extends AbstractWizardModel { - public InitPodWizardModel(Context context) { - super(context); - } - - @Override - public Fragment getReviewFragment() { - return PodInfoFragment.create("initPodInfoFragment", true); - } -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/pages/PodInfoPage.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/pages/PodInfoPage.java deleted file mode 100644 index 04ca08a0f3..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/pages/PodInfoPage.java +++ /dev/null @@ -1,34 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.pages; - -import androidx.fragment.app.Fragment; - -import com.tech.freak.wizardpager.model.ModelCallbacks; -import com.tech.freak.wizardpager.model.Page; -import com.tech.freak.wizardpager.model.ReviewItem; - -import java.util.ArrayList; - - -/** - * Created by andy on 12/11/2019 - */ -public class PodInfoPage extends Page { - - public PodInfoPage(ModelCallbacks callbacks, String title) { - super(callbacks, title); - } - - @Override - public Fragment createFragment() { - return PodInfoFragment.create(getKey(), true); - } - - @Override - public void getReviewItems(ArrayList dest) { - } - - @Override - public boolean isCompleted() { - return true; - } -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/OmnipodPumpStatus.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/OmnipodPumpStatus.java deleted file mode 100644 index f1c0474829..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/OmnipodPumpStatus.java +++ /dev/null @@ -1,162 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.driver; - -import java.util.Arrays; - -import javax.inject.Inject; -import javax.inject.Singleton; - -import info.nightscout.androidaps.plugins.bus.RxBusWrapper; -import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus; -import info.nightscout.androidaps.plugins.pump.common.data.TempBasalPair; -import info.nightscout.androidaps.plugins.pump.common.defs.PumpDeviceState; -import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; -import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange; -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil; -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.data.RLHistoryItem; -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; -import info.nightscout.androidaps.utils.sharedPreferences.SP; - -/** - * Created by andy on 4.8.2019 - */ -@Singleton -@Deprecated -public class OmnipodPumpStatus extends PumpStatus { - // TODO remove all fields that can also be obtained via PodStateManager - // We can probably get rid of this class altogether - - private final SP sp; - private final RileyLinkUtil rileyLinkUtil; - private final RxBusWrapper rxBus; - - public String rileyLinkErrorDescription = null; - public String rileyLinkAddress = null; - public boolean inPreInit = true; - - // statuses - public double currentBasal = 0; - public long tempBasalStart; - public long tempBasalEnd; - public Double tempBasalAmount = 0.0d; - public Integer tempBasalLength; - public long tempBasalPumpId; - public PumpType pumpType; - - public String regexMac = "([\\da-fA-F]{1,2}(?:\\:|$)){6}"; - - public boolean beepBolusEnabled = true; - public boolean beepBasalEnabled = true; - public boolean beepSMBEnabled = true; - public boolean beepTBREnabled = true; - public boolean podDebuggingOptionsEnabled = false; - public boolean timeChangeEventEnabled = true; - - private PumpDeviceState pumpDeviceState; - - @Inject - public OmnipodPumpStatus(SP sp, - RxBusWrapper rxBus, - RileyLinkUtil rileyLinkUtil) { - super(PumpType.Insulet_Omnipod); - this.sp = sp; - this.rxBus = rxBus; - this.rileyLinkUtil = rileyLinkUtil; - initSettings(); - } - - @Override - public void initSettings() { - this.activeProfileName = ""; - this.reservoirRemainingUnits = 75d; - this.batteryRemaining = 75; - this.lastConnection = sp.getLong(OmnipodConst.Statistics.LastGoodPumpCommunicationTime, 0L); - this.pumpType = PumpType.Insulet_Omnipod; - } - - // For Omnipod, this method only returns a RileyLink error description - @Override - public String getErrorInfo() { - return this.rileyLinkErrorDescription; - } - -// public boolean setNotInPreInit() { -// this.inPreInit = false; -// -// return reconfigureService(); -// } - - - public void clearTemporaryBasal() { - this.tempBasalStart = 0L; - this.tempBasalEnd = 0L; - this.tempBasalAmount = 0.0d; - this.tempBasalLength = 0; - } - - - public TempBasalPair getTemporaryBasal() { - - TempBasalPair tbr = new TempBasalPair(); - tbr.setDurationMinutes(tempBasalLength); - tbr.setInsulinRate(tempBasalAmount); - tbr.setStartTime(tempBasalStart); - tbr.setEndTime(tempBasalEnd); - - return tbr; - } - - @Override - public String toString() { - return "OmnipodPumpStatus{" + - "rileyLinkErrorDescription='" + rileyLinkErrorDescription + '\'' + - ", rileyLinkAddress='" + rileyLinkAddress + '\'' + - ", inPreInit=" + inPreInit + - ", tempBasalStart=" + tempBasalStart + - ", tempBasalEnd=" + tempBasalEnd + - ", tempBasalAmount=" + tempBasalAmount + - ", tempBasalLength=" + tempBasalLength + - ", regexMac='" + regexMac + '\'' + - ", lastDataTime=" + lastDataTime + - ", lastConnection=" + lastConnection + - ", previousConnection=" + previousConnection + - ", lastBolusTime=" + lastBolusTime + - ", lastBolusAmount=" + lastBolusAmount + - ", activeProfileName='" + activeProfileName + '\'' + - ", reservoirRemainingUnits=" + reservoirRemainingUnits + - ", reservoirFullUnits=" + reservoirFullUnits + - ", batteryRemaining=" + batteryRemaining + - ", batteryVoltage=" + batteryVoltage + - ", iob='" + iob + '\'' + - ", dailyTotalUnits=" + dailyTotalUnits + - ", maxDailyTotalUnits='" + maxDailyTotalUnits + '\'' + - ", validBasalRateProfileSelectedOnPump=" + validBasalRateProfileSelectedOnPump + - ", pumpType=" + pumpType + - ", profileStore=" + profileStore + - ", units='" + units + '\'' + - ", pumpStatusType=" + pumpStatusType + - ", basalsByHour=" + Arrays.toString(basalsByHour) + - ", currentBasal=" + currentBasal + - ", tempBasalInProgress=" + tempBasalInProgress + - ", tempBasalRatio=" + tempBasalRatio + - ", tempBasalRemainMin=" + tempBasalRemainMin + - ", tempBasalStart=" + tempBasalStart + - ", pumpType=" + pumpType + - "} "; - } - - - public PumpDeviceState getPumpDeviceState() { - return pumpDeviceState; - } - - - public void setPumpDeviceState(PumpDeviceState pumpDeviceState) { - this.pumpDeviceState = pumpDeviceState; - - rileyLinkUtil.getRileyLinkHistory().add(new RLHistoryItem(pumpDeviceState, RileyLinkTargetDevice.Omnipod)); - - rxBus.send(new EventRileyLinkDeviceStatusChange(pumpDeviceState)); - } - -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java deleted file mode 100644 index 14ee37ea95..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsPodStateManager.java +++ /dev/null @@ -1,108 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.driver.comm; - -import java.util.Date; -import java.util.Objects; - -import javax.inject.Inject; -import javax.inject.Singleton; - -import info.nightscout.androidaps.events.Event; -import info.nightscout.androidaps.events.EventRefreshOverview; -import info.nightscout.androidaps.logging.AAPSLogger; -import info.nightscout.androidaps.plugins.bus.RxBusWrapper; -import info.nightscout.androidaps.plugins.pump.common.defs.PumpStatusType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodPumpValuesChanged; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; -import info.nightscout.androidaps.utils.DateUtil; -import info.nightscout.androidaps.utils.resources.ResourceHelper; -import info.nightscout.androidaps.utils.sharedPreferences.SP; - -@Singleton -public class AapsPodStateManager extends PodStateManager { - private final AAPSLogger aapsLogger; - private final SP sp; - private final OmnipodPumpStatus omnipodPumpStatus; - private final RxBusWrapper rxBus; - - @Inject - public AapsPodStateManager(AAPSLogger aapsLogger, SP sp, OmnipodPumpStatus omnipodPumpStatus, - RxBusWrapper rxBus) { - super(aapsLogger); - - if (aapsLogger == null) { - throw new IllegalArgumentException("aapsLogger can not be null"); - } - if (sp == null) { - throw new IllegalArgumentException("sp can not be null"); - } - if (omnipodPumpStatus == null) { - throw new IllegalArgumentException("omnipodPumpStatus can not be null"); - } - if (rxBus == null) { - throw new IllegalArgumentException("rxBus can not be null"); - } - - this.aapsLogger = aapsLogger; - this.sp = sp; - this.omnipodPumpStatus = omnipodPumpStatus; - this.rxBus = rxBus; - } - - @Override - protected String readPodState() { - return sp.getString(OmnipodConst.Prefs.PodState, ""); - } - - @Override - protected void storePodState(String podState) { - sp.putString(OmnipodConst.Prefs.PodState, podState); - } - - @Override - protected void notifyPodStateChanged() { - if (!hasPodState()) { - omnipodPumpStatus.lastBolusTime = null; - omnipodPumpStatus.lastBolusAmount = null; - omnipodPumpStatus.reservoirRemainingUnits = 0.0; - // TODO this does not seem to set the pump status to suspended anymore - // Also, verify that AAPS is aware that no insulin is delivered anymore at this point - omnipodPumpStatus.pumpStatusType = PumpStatusType.Suspended; - sendEvent(new EventRefreshOverview("Omnipod Pump", false)); - } else { - Date lastBolusStartTime = getLastBolusStartTime() == null ? null : getLastBolusStartTime().toDate(); - Double lastBolusAmount = getLastBolusAmount(); - - // Update other info: last bolus, units remaining, suspended - boolean suspended = isSuspended() || !isPodRunning(); - if (Objects.equals(lastBolusStartTime, omnipodPumpStatus.lastBolusTime) // - || !Objects.equals(lastBolusAmount, omnipodPumpStatus.lastBolusAmount) // - || !isReservoirStatusUpToDate(omnipodPumpStatus, getReservoirLevel()) - || suspended != PumpStatusType.Suspended.equals(omnipodPumpStatus.pumpStatusType)) { - omnipodPumpStatus.lastBolusTime = lastBolusStartTime; - omnipodPumpStatus.lastBolusAmount = lastBolusAmount; - omnipodPumpStatus.reservoirRemainingUnits = getReservoirLevel() == null ? 75.0 : getReservoirLevel(); - - boolean sendRefreshOverviewEvent = suspended != PumpStatusType.Suspended.equals(omnipodPumpStatus.pumpStatusType); - // TODO this does not seem to set the pump status to suspended anymore - // Also, verify that AAPS is aware that no insulin is delivered anymore at this point - omnipodPumpStatus.pumpStatusType = suspended ? PumpStatusType.Suspended : PumpStatusType.Running; - - if (sendRefreshOverviewEvent) { - sendEvent(new EventRefreshOverview("Omnipod Pump", false)); - } - } - } - sendEvent(new EventOmnipodPumpValuesChanged()); - } - - private static boolean isReservoirStatusUpToDate(OmnipodPumpStatus pumpStatus, Double unitsRemaining) { - double expectedUnitsRemaining = unitsRemaining == null ? 75.0 : unitsRemaining; - return Math.abs(expectedUnitsRemaining - pumpStatus.reservoirRemainingUnits) < 0.000001; - } - - private void sendEvent(Event event) { - rxBus.send(event); - } -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/AcknowledgeAlertsAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/AcknowledgeAlertsAction.java similarity index 56% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/AcknowledgeAlertsAction.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/AcknowledgeAlertsAction.java index 3ffbc5942f..6ae13b159c 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/AcknowledgeAlertsAction.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/AcknowledgeAlertsAction.java @@ -1,14 +1,14 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.action; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action; import java.util.Collections; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.AcknowledgeAlertsCommand; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSet; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSlot; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.AcknowledgeAlertsCommand; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertSet; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertSlot; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.ActionInitializationException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; public class AcknowledgeAlertsAction implements OmnipodAction { private final PodStateManager podStateManager; @@ -32,7 +32,7 @@ public class AcknowledgeAlertsAction implements OmnipodAction { } @Override - public StatusResponse execute(OmnipodCommunicationManager communicationService) { + public StatusResponse execute(OmnipodRileyLinkCommunicationManager communicationService) { return communicationService.sendCommand(StatusResponse.class, podStateManager, new AcknowledgeAlertsCommand(podStateManager.getCurrentNonce(), alerts)); } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/AssignAddressAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/AssignAddressAction.java similarity index 62% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/AssignAddressAction.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/AssignAddressAction.java index 369c50c48e..9f8fc4296a 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/AssignAddressAction.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/AssignAddressAction.java @@ -1,20 +1,20 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.action; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action; import org.joda.time.DateTimeZone; import java.util.Collections; import java.util.Random; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalMessageAddressException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalPodProgressException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalVersionResponseTypeException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.OmnipodMessage; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.AssignAddressCommand; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.VersionResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodProgressStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.OmnipodMessage; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.AssignAddressCommand; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.VersionResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalMessageAddressException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalVersionResponseTypeException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; public class AssignAddressAction implements OmnipodAction { private final PodStateManager podStateManager; @@ -27,7 +27,7 @@ public class AssignAddressAction implements OmnipodAction { } @Override - public VersionResponse execute(OmnipodCommunicationManager communicationService) { + public VersionResponse execute(OmnipodRileyLinkCommunicationManager communicationService) { if (!podStateManager.hasPodState()) { podStateManager.initState(generateRandomAddress()); } @@ -36,11 +36,11 @@ public class AssignAddressAction implements OmnipodAction { } AssignAddressCommand assignAddress = new AssignAddressCommand(podStateManager.getAddress()); - OmnipodMessage assignAddressMessage = new OmnipodMessage(OmnipodConst.DEFAULT_ADDRESS, + OmnipodMessage assignAddressMessage = new OmnipodMessage(OmnipodConstants.DEFAULT_ADDRESS, Collections.singletonList(assignAddress), podStateManager.getMessageNumber()); VersionResponse assignAddressResponse = communicationService.exchangeMessages(VersionResponse.class, podStateManager, assignAddressMessage, - OmnipodConst.DEFAULT_ADDRESS, podStateManager.getAddress()); + OmnipodConstants.DEFAULT_ADDRESS, podStateManager.getAddress()); if (!assignAddressResponse.isAssignAddressVersionResponse()) { throw new IllegalVersionResponseTypeException("assignAddress", "setupPod"); diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/BolusAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/BolusAction.java similarity index 66% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/BolusAction.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/BolusAction.java index c57d2b3615..ed785add66 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/BolusAction.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/BolusAction.java @@ -1,17 +1,17 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.action; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action; import org.joda.time.Duration; import java.util.Arrays; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.OmnipodMessage; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.BolusExtraCommand; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.SetInsulinScheduleCommand; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BolusDeliverySchedule; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.OmnipodMessage; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.BolusExtraCommand; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.SetInsulinScheduleCommand; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BolusDeliverySchedule; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.ActionInitializationException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; public class BolusAction implements OmnipodAction { private final PodStateManager podStateManager; @@ -40,7 +40,7 @@ public class BolusAction implements OmnipodAction { } @Override - public StatusResponse execute(OmnipodCommunicationManager communicationService) { + public StatusResponse execute(OmnipodRileyLinkCommunicationManager communicationService) { BolusDeliverySchedule bolusDeliverySchedule = new BolusDeliverySchedule(units, timeBetweenPulses); SetInsulinScheduleCommand setInsulinScheduleCommand = new SetInsulinScheduleCommand( podStateManager.getCurrentNonce(), bolusDeliverySchedule); diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/CancelDeliveryAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/CancelDeliveryAction.java similarity index 67% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/CancelDeliveryAction.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/CancelDeliveryAction.java index c29135a24f..7b83b3ee96 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/CancelDeliveryAction.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/CancelDeliveryAction.java @@ -1,18 +1,18 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.action; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.MessageBlock; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.OmnipodMessage; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.CancelDeliveryCommand; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.BeepType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.DeliveryType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.MessageBlock; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.OmnipodMessage; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.CancelDeliveryCommand; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.BeepType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.ActionInitializationException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; public class CancelDeliveryAction implements OmnipodAction { private final PodStateManager podStateManager; @@ -33,7 +33,7 @@ public class CancelDeliveryAction implements OmnipodAction { } @Override - public StatusResponse execute(OmnipodCommunicationManager communicationService) { + public StatusResponse execute(OmnipodRileyLinkCommunicationManager communicationService) { List messageBlocks = new ArrayList<>(); if (acknowledgementBeep && deliveryTypes.size() > 1) { @@ -52,9 +52,7 @@ public class CancelDeliveryAction implements OmnipodAction { StatusResponse statusResponse = communicationService.exchangeMessages(StatusResponse.class, podStateManager, new OmnipodMessage(podStateManager.getAddress(), messageBlocks, podStateManager.getMessageNumber())); - if (deliveryTypes.contains(DeliveryType.TEMP_BASAL)) { - podStateManager.setLastTempBasal(null, null, null); - } + return statusResponse; } } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/ConfigureAlertsAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/ConfigureAlertsAction.java new file mode 100644 index 0000000000..bc4235c2e0 --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/ConfigureAlertsAction.java @@ -0,0 +1,44 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action; + +import java.util.List; + +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.ConfigureAlertsCommand; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertConfiguration; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.ActionInitializationException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; + +public class ConfigureAlertsAction implements OmnipodAction { + private final PodStateManager podStateManager; + private final List alertConfigurations; + + public ConfigureAlertsAction(PodStateManager podStateManager, List alertConfigurations) { + if (podStateManager == null) { + throw new ActionInitializationException("Pod state manager cannot be null"); + } + if (alertConfigurations == null) { + throw new ActionInitializationException("Alert configurations cannot be null"); + } + this.podStateManager = podStateManager; + this.alertConfigurations = alertConfigurations; + } + + @Override + public StatusResponse execute(OmnipodRileyLinkCommunicationManager communicationService) { + ConfigureAlertsCommand configureAlertsCommand = new ConfigureAlertsCommand(podStateManager.getCurrentNonce(), alertConfigurations); + StatusResponse statusResponse = communicationService.sendCommand(StatusResponse.class, podStateManager, configureAlertsCommand); + updateConfiguredAlerts(podStateManager, alertConfigurations); + return statusResponse; + } + + public static void updateConfiguredAlerts(PodStateManager podStateManager, List alertConfigurations) { + for (AlertConfiguration alertConfiguration : alertConfigurations) { + if (alertConfiguration.isActive()) { + podStateManager.putConfiguredAlert(alertConfiguration.getAlertSlot(), alertConfiguration.getAlertType()); + } else { + podStateManager.removeConfiguredAlert(alertConfiguration.getAlertSlot()); + } + } + } +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/DeactivatePodAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/DeactivatePodAction.java similarity index 51% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/DeactivatePodAction.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/DeactivatePodAction.java index 7d1645c473..efe855b82f 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/DeactivatePodAction.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/DeactivatePodAction.java @@ -1,14 +1,14 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.action; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action; import java.util.EnumSet; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.PodFaultException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.DeactivatePodCommand; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.DeliveryType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.DeactivatePodCommand; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.ActionInitializationException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.PodFaultException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; public class DeactivatePodAction implements OmnipodAction { private final PodStateManager podStateManager; @@ -23,8 +23,8 @@ public class DeactivatePodAction implements OmnipodAction { } @Override - public StatusResponse execute(OmnipodCommunicationManager communicationService) { - if (!podStateManager.isSuspended() && !podStateManager.hasFaultEvent()) { + public StatusResponse execute(OmnipodRileyLinkCommunicationManager communicationService) { + if (!podStateManager.isSuspended() && !podStateManager.isPodFaulted()) { try { communicationService.executeAction(new CancelDeliveryAction(podStateManager, EnumSet.allOf(DeliveryType.class), acknowledgementBeep)); diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/GetPodInfoAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/GetPodInfoAction.java new file mode 100644 index 0000000000..cc925c6e4c --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/GetPodInfoAction.java @@ -0,0 +1,29 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action; + +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.GetStatusCommand; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.ActionInitializationException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; + +public class GetPodInfoAction implements OmnipodAction { + private final PodStateManager podStateManager; + private final PodInfoType podInfoType; + + public GetPodInfoAction(PodStateManager podStateManager, PodInfoType podInfoType) { + if (podStateManager == null) { + throw new ActionInitializationException("Pod state manager cannot be null"); + } + if (podInfoType == null) { + throw new ActionInitializationException("Pod info type cannot be null"); + } + this.podStateManager = podStateManager; + this.podInfoType = podInfoType; + } + + @Override + public PodInfoResponse execute(OmnipodRileyLinkCommunicationManager communicationService) { + return communicationService.sendCommand(PodInfoResponse.class, podStateManager, new GetStatusCommand(podInfoType)); + } +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/GetStatusAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/GetStatusAction.java new file mode 100644 index 0000000000..aac7b55d6c --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/GetStatusAction.java @@ -0,0 +1,24 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action; + +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.GetStatusCommand; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.ActionInitializationException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; + +public class GetStatusAction implements OmnipodAction { + private final PodStateManager podStateManager; + + public GetStatusAction(PodStateManager podState) { + if (podState == null) { + throw new ActionInitializationException("Pod state manager cannot be null"); + } + this.podStateManager = podState; + } + + @Override + public StatusResponse execute(OmnipodRileyLinkCommunicationManager communicationService) { + return communicationService.sendCommand(StatusResponse.class, podStateManager, new GetStatusCommand(PodInfoType.NORMAL)); + } +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/InsertCannulaAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/InsertCannulaAction.java new file mode 100644 index 0000000000..b364aa8c81 --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/InsertCannulaAction.java @@ -0,0 +1,75 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action; + +import org.joda.time.Duration; + +import java.util.List; +import java.util.Optional; + +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.service.ExpirationReminderBuilder; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertConfiguration; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalSchedule; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.ActionInitializationException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; + +public class InsertCannulaAction implements OmnipodAction { + + private final PodStateManager podStateManager; + private final BasalSchedule initialBasalSchedule; + private final Duration expirationReminderTimeBeforeShutdown; + private final Integer lowReservoirAlertUnits; + + public InsertCannulaAction(PodStateManager podStateManager, BasalSchedule initialBasalSchedule, + Duration expirationReminderTimeBeforeShutdown, Integer lowReservoirAlertUnits) { + if (podStateManager == null) { + throw new ActionInitializationException("Pod state manager cannot be null"); + } + if (initialBasalSchedule == null) { + throw new ActionInitializationException("Initial basal schedule cannot be null"); + } + this.podStateManager = podStateManager; + this.initialBasalSchedule = initialBasalSchedule; + this.expirationReminderTimeBeforeShutdown = expirationReminderTimeBeforeShutdown; + this.lowReservoirAlertUnits = lowReservoirAlertUnits; + } + + @Override + public StatusResponse execute(OmnipodRileyLinkCommunicationManager communicationService) { + if (!podStateManager.isPodInitialized() || podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.PRIMING_COMPLETED)) { + throw new IllegalPodProgressException(PodProgressStatus.PRIMING_COMPLETED, podStateManager.isPodInitialized() ? podStateManager.getPodProgressStatus() : null); + } + + if (podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.BASAL_INITIALIZED)) { + podStateManager.setBasalSchedule(initialBasalSchedule); + communicationService.executeAction(new SetBasalScheduleAction(podStateManager, initialBasalSchedule, + true, podStateManager.getScheduleOffset(), false)); + } + + if (podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.INSERTING_CANNULA)) { + communicationService.executeAction(new ConfigureAlertsAction(podStateManager, buildAlertConfigurations())); + + podStateManager.setExpirationAlertTimeBeforeShutdown(expirationReminderTimeBeforeShutdown); + podStateManager.setLowReservoirAlertUnits(lowReservoirAlertUnits); + + return communicationService.executeAction(new BolusAction(podStateManager, OmnipodConstants.POD_CANNULA_INSERTION_BOLUS_UNITS, + Duration.standardSeconds(1), false, false)); + } else if (podStateManager.getPodProgressStatus().equals(PodProgressStatus.INSERTING_CANNULA)) { + // Check status + return communicationService.executeAction(new GetStatusAction(podStateManager)); + } else { + throw new IllegalPodProgressException(null, podStateManager.getPodProgressStatus()); + } + } + + private List buildAlertConfigurations() { + ExpirationReminderBuilder builder = new ExpirationReminderBuilder(podStateManager).defaults(); + builder.expirationAdvisory(expirationReminderTimeBeforeShutdown != null, + Optional.ofNullable(expirationReminderTimeBeforeShutdown).orElse(Duration.ZERO)); + builder.lowReservoir(lowReservoirAlertUnits != null, Optional.ofNullable(lowReservoirAlertUnits).orElse(0)); + return builder.build(); + } +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/OmnipodAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/OmnipodAction.java new file mode 100644 index 0000000000..e979297a15 --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/OmnipodAction.java @@ -0,0 +1,7 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action; + +import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; + +public interface OmnipodAction { + T execute(OmnipodRileyLinkCommunicationManager communicationService); +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/PrimeAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/PrimeAction.java similarity index 58% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/PrimeAction.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/PrimeAction.java index 81289b7d5f..115ad1c6b1 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/PrimeAction.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/PrimeAction.java @@ -1,12 +1,12 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.action; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.service.PrimeService; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalPodProgressException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodProgressStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.service.PrimeService; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.ActionInitializationException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; public class PrimeAction implements OmnipodAction { @@ -25,12 +25,14 @@ public class PrimeAction implements OmnipodAction { } @Override - public StatusResponse execute(OmnipodCommunicationManager communicationService) { + public StatusResponse execute(OmnipodRileyLinkCommunicationManager communicationService) { if (!podStateManager.isPodInitialized() || podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.PAIRING_COMPLETED)) { throw new IllegalPodProgressException(PodProgressStatus.PAIRING_COMPLETED, podStateManager.isPodInitialized() ? podStateManager.getPodProgressStatus() : null); } if (podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.PRIMING)) { - service.executeDisableTab5Sub16FaultConfigCommand(communicationService, podStateManager); + // FaultConfigCommand sets internal pod variables to effectively disable $6x faults which occur more often with a 0 TBR + service.executeDisableTab5Sub16And17FaultConfigCommand(communicationService, podStateManager); + service.executeFinishSetupReminderAlertCommand(communicationService, podStateManager); return service.executePrimeBolusCommand(communicationService, podStateManager); } else if (podStateManager.getPodProgressStatus().equals(PodProgressStatus.PRIMING)) { diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetBasalScheduleAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/SetBasalScheduleAction.java similarity index 61% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetBasalScheduleAction.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/SetBasalScheduleAction.java index 1a4fd91237..a64766c5d3 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetBasalScheduleAction.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/SetBasalScheduleAction.java @@ -1,17 +1,17 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.action; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action; import org.joda.time.Duration; import java.util.Arrays; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.OmnipodMessage; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.BasalScheduleExtraCommand; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.SetInsulinScheduleCommand; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BasalSchedule; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.OmnipodMessage; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.BasalScheduleExtraCommand; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.SetInsulinScheduleCommand; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalSchedule; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.ActionInitializationException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; public class SetBasalScheduleAction implements OmnipodAction { private final PodStateManager podStateManager; @@ -39,15 +39,13 @@ public class SetBasalScheduleAction implements OmnipodAction { } @Override - public StatusResponse execute(OmnipodCommunicationManager communicationService) { + public StatusResponse execute(OmnipodRileyLinkCommunicationManager communicationService) { SetInsulinScheduleCommand setBasal = new SetInsulinScheduleCommand(podStateManager.getCurrentNonce(), basalSchedule, scheduleOffset); BasalScheduleExtraCommand extraCommand = new BasalScheduleExtraCommand(basalSchedule, scheduleOffset, acknowledgementBeep, confidenceReminder, Duration.ZERO); OmnipodMessage basalMessage = new OmnipodMessage(podStateManager.getAddress(), Arrays.asList(setBasal, extraCommand), podStateManager.getMessageNumber()); - StatusResponse statusResponse = communicationService.exchangeMessages(StatusResponse.class, podStateManager, basalMessage); - podStateManager.setBasalSchedule(basalSchedule); - return statusResponse; + return communicationService.exchangeMessages(StatusResponse.class, podStateManager, basalMessage); } } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetTempBasalAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/SetTempBasalAction.java similarity index 52% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetTempBasalAction.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/SetTempBasalAction.java index 3f908c1a3a..cadb602f68 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetTempBasalAction.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/SetTempBasalAction.java @@ -1,20 +1,18 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.action; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action; -import org.joda.time.DateTime; import org.joda.time.Duration; import java.util.Arrays; import java.util.List; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.MessageBlock; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.OmnipodMessage; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.SetInsulinScheduleCommand; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.TempBasalExtraCommand; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.MessageBlock; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.OmnipodMessage; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.SetInsulinScheduleCommand; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.TempBasalExtraCommand; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.ActionInitializationException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; public class SetTempBasalAction implements OmnipodAction { private final PodStateManager podStateManager; @@ -39,14 +37,12 @@ public class SetTempBasalAction implements OmnipodAction { } @Override - public StatusResponse execute(OmnipodCommunicationManager communicationService) { + public StatusResponse execute(OmnipodRileyLinkCommunicationManager communicationService) { List messageBlocks = Arrays.asList( // new SetInsulinScheduleCommand(podStateManager.getCurrentNonce(), rate, duration), new TempBasalExtraCommand(rate, duration, acknowledgementBeep, completionBeep, Duration.ZERO)); OmnipodMessage message = new OmnipodMessage(podStateManager.getAddress(), messageBlocks, podStateManager.getMessageNumber()); - StatusResponse statusResponse = communicationService.exchangeMessages(StatusResponse.class, podStateManager, message); - podStateManager.setLastTempBasal(DateTime.now().minus(OmnipodConst.AVERAGE_TEMP_BASAL_COMMAND_COMMUNICATION_DURATION), rate, duration); - return statusResponse; + return communicationService.exchangeMessages(StatusResponse.class, podStateManager, message); } } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetupPodAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/SetupPodAction.java similarity index 57% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetupPodAction.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/SetupPodAction.java index 5416346f8e..f811e711db 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/action/SetupPodAction.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/SetupPodAction.java @@ -1,19 +1,19 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.action; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action; import org.joda.time.DateTime; import java.util.Collections; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalMessageAddressException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalPodProgressException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalVersionResponseTypeException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.OmnipodMessage; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.SetupPodCommand; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.VersionResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodProgressStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.OmnipodMessage; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.SetupPodCommand; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.VersionResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalMessageAddressException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalVersionResponseTypeException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; public class SetupPodAction implements OmnipodAction { private final PodStateManager podStateManager; @@ -26,7 +26,7 @@ public class SetupPodAction implements OmnipodAction { } @Override - public VersionResponse execute(OmnipodCommunicationManager communicationService) { + public VersionResponse execute(OmnipodRileyLinkCommunicationManager communicationService) { if (!podStateManager.isPodInitialized() || !podStateManager.getPodProgressStatus().equals(PodProgressStatus.REMINDER_INITIALIZED)) { throw new IllegalPodProgressException(PodProgressStatus.REMINDER_INITIALIZED, podStateManager.isPodInitialized() ? podStateManager.getPodProgressStatus() : null); } @@ -34,11 +34,11 @@ public class SetupPodAction implements OmnipodAction { SetupPodCommand setupPodCommand = new SetupPodCommand(podStateManager.getAddress(), activationDate, podStateManager.getLot(), podStateManager.getTid()); - OmnipodMessage message = new OmnipodMessage(OmnipodConst.DEFAULT_ADDRESS, + OmnipodMessage message = new OmnipodMessage(OmnipodConstants.DEFAULT_ADDRESS, Collections.singletonList(setupPodCommand), podStateManager.getMessageNumber()); VersionResponse setupPodResponse; setupPodResponse = communicationService.exchangeMessages(VersionResponse.class, podStateManager, - message, OmnipodConst.DEFAULT_ADDRESS, podStateManager.getAddress()); + message, OmnipodConstants.DEFAULT_ADDRESS, podStateManager.getAddress()); if (!setupPodResponse.isSetupPodVersionResponse()) { throw new IllegalVersionResponseTypeException("setupPod", "assignAddress"); diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/service/ExpirationReminderBuilder.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/service/ExpirationReminderBuilder.java new file mode 100644 index 0000000000..990bed5de6 --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/service/ExpirationReminderBuilder.java @@ -0,0 +1,69 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.service; + +import org.joda.time.DateTime; +import org.joda.time.Duration; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertConfiguration; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertSlot; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.util.AlertConfigurationUtil; + +public final class ExpirationReminderBuilder { + private final Map alerts = new HashMap<>(); + private final DateTime endOfServiceTime; + private final PodStateManager podStateManager; + + public ExpirationReminderBuilder(PodStateManager podStateManager) { + this.endOfServiceTime = podStateManager.getActivatedAt().plus(OmnipodConstants.SERVICE_DURATION); + this.podStateManager = podStateManager; + } + + public ExpirationReminderBuilder defaults() { + DateTime shutdownImminentAlarmTime = endOfServiceTime.minus(OmnipodConstants.END_OF_SERVICE_IMMINENT_WINDOW); + + if (DateTime.now().isBefore(shutdownImminentAlarmTime)) { + Duration timeUntilShutdownImminentAlarm = new Duration(DateTime.now(), + shutdownImminentAlarmTime); + AlertConfiguration shutdownImminentAlertConfiguration = AlertConfigurationUtil.createShutdownImminentAlertConfiguration( + timeUntilShutdownImminentAlarm); + alerts.put(shutdownImminentAlertConfiguration.getAlertSlot(), shutdownImminentAlertConfiguration); + } + + AlertConfiguration autoOffAlertConfiguration = AlertConfigurationUtil.createAutoOffAlertConfiguration( + false, Duration.ZERO); + alerts.put(autoOffAlertConfiguration.getAlertSlot(), autoOffAlertConfiguration); + + return this; + } + + public ExpirationReminderBuilder expirationAdvisory(boolean active, Duration timeBeforeShutdown) { + DateTime expirationAdvisoryAlarmTime = endOfServiceTime.minus(timeBeforeShutdown); + + if (DateTime.now().isBefore(expirationAdvisoryAlarmTime)) { + Duration timeUntilExpirationAdvisoryAlarm = new Duration(DateTime.now(), + expirationAdvisoryAlarmTime); + AlertConfiguration expirationAdvisoryAlertConfiguration = AlertConfigurationUtil.createExpirationAdvisoryAlertConfiguration(active, + timeUntilExpirationAdvisoryAlarm, timeBeforeShutdown); + alerts.put(expirationAdvisoryAlertConfiguration.getAlertSlot(), expirationAdvisoryAlertConfiguration); + } + return this; + } + + public ExpirationReminderBuilder lowReservoir(boolean active, int units) { + if (podStateManager.getReservoirLevel() == null || podStateManager.getReservoirLevel().intValue() > units) { + AlertConfiguration lowReservoirAlertConfiguration = AlertConfigurationUtil.createLowReservoirAlertConfiguration(active, (double) units); + alerts.put(lowReservoirAlertConfiguration.getAlertSlot(), lowReservoirAlertConfiguration); + } + return this; + } + + public List build() { + return new ArrayList<>(alerts.values()); + } +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/service/PrimeService.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/service/PrimeService.java new file mode 100644 index 0000000000..062731e002 --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/service/PrimeService.java @@ -0,0 +1,37 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.service; + +import org.joda.time.Duration; + +import java.util.Collections; + +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.BolusAction; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.ConfigureAlertsAction; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.OmnipodMessage; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.FaultConfigCommand; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertConfiguration; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.util.AlertConfigurationUtil; +import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; + +public class PrimeService { + + public StatusResponse executeDisableTab5Sub16And17FaultConfigCommand(OmnipodRileyLinkCommunicationManager communicationService, PodStateManager podStateManager) { + FaultConfigCommand faultConfigCommand = new FaultConfigCommand(podStateManager.getCurrentNonce(), (byte) 0x00, (byte) 0x00); + OmnipodMessage faultConfigMessage = new OmnipodMessage(podStateManager.getAddress(), + Collections.singletonList(faultConfigCommand), podStateManager.getMessageNumber()); + return communicationService.exchangeMessages(StatusResponse.class, podStateManager, faultConfigMessage); + } + + public StatusResponse executeFinishSetupReminderAlertCommand(OmnipodRileyLinkCommunicationManager communicationService, PodStateManager podStateManager) { + AlertConfiguration finishSetupReminderAlertConfiguration = AlertConfigurationUtil.createFinishSetupReminderAlertConfiguration(); + return communicationService.executeAction(new ConfigureAlertsAction(podStateManager, + Collections.singletonList(finishSetupReminderAlertConfiguration))); + } + + public StatusResponse executePrimeBolusCommand(OmnipodRileyLinkCommunicationManager communicationService, PodStateManager podStateManager) { + return communicationService.executeAction(new BolusAction(podStateManager, OmnipodConstants.POD_PRIME_BOLUS_UNITS, + Duration.standardSeconds(1), false, false)); + } +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/IRawRepresentable.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/IRawRepresentable.java new file mode 100644 index 0000000000..5d706e5087 --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/IRawRepresentable.java @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message; + +public interface IRawRepresentable { + byte[] getRawData(); +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/MessageBlock.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/MessageBlock.java similarity index 80% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/MessageBlock.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/MessageBlock.java index dba0035df7..8cfb0277f2 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/MessageBlock.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/MessageBlock.java @@ -1,14 +1,14 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message; import java.io.ByteArrayOutputStream; import java.io.IOException; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.MessageBlockType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.MessageBlockType; public abstract class MessageBlock { protected byte[] encodedData = new byte[0]; - public MessageBlock() { + protected MessageBlock() { } public abstract MessageBlockType getType(); diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/NonceResyncableMessageBlock.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/NonceResyncableMessageBlock.java similarity index 64% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/NonceResyncableMessageBlock.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/NonceResyncableMessageBlock.java index 6170164366..7aad28e522 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/NonceResyncableMessageBlock.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/NonceResyncableMessageBlock.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message; public abstract class NonceResyncableMessageBlock extends MessageBlock { public abstract int getNonce(); diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/OmnipodMessage.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/OmnipodMessage.java similarity index 85% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/OmnipodMessage.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/OmnipodMessage.java index e302d90461..995121c1c3 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/OmnipodMessage.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/OmnipodMessage.java @@ -1,16 +1,16 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message; import java.util.ArrayList; import java.util.List; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.CrcMismatchException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.MessageDecodingException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.NotEnoughDataException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.GetStatusCommand; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.MessageBlockType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmniCRC; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.GetStatusCommand; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.MessageBlockType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodCrc; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.CrcMismatchException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.MessageDecodingException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.NotEnoughDataException; public class OmnipodMessage { @@ -44,7 +44,7 @@ public class OmnipodMessage { } int sequenceNumber = (((int) b9 >> 2) & 0b11111); int crc = ByteUtil.toInt(data[data.length - 2], data[data.length - 1]); - int calculatedCrc = OmniCRC.crc16(ByteUtil.substring(data, 0, data.length - 2)); + int calculatedCrc = OmnipodCrc.crc16(ByteUtil.substring(data, 0, data.length - 2)); if (crc != calculatedCrc) { throw new CrcMismatchException(calculatedCrc, crc); } @@ -86,7 +86,7 @@ public class OmnipodMessage { header = ByteUtil.concat(header, (byte) (((sequenceNumber & 0x1F) << 2) + ((encodedData.length >> 8) & 0x03))); header = ByteUtil.concat(header, (byte) (encodedData.length & 0xFF)); encodedData = ByteUtil.concat(header, encodedData); - int crc = OmniCRC.crc16(encodedData); + int crc = OmnipodCrc.crc16(encodedData); encodedData = ByteUtil.concat(encodedData, ByteUtil.substring(ByteUtil.getBytesFromInt(crc), 2, 2)); return encodedData; } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/OmnipodPacket.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/OmnipodPacket.java similarity index 82% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/OmnipodPacket.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/OmnipodPacket.java index 4bbe035519..34f28c0d3b 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/OmnipodPacket.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/OmnipodPacket.java @@ -1,11 +1,11 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.RLMessage; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.CrcMismatchException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalPacketTypeException; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PacketType; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmniCRC; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodCrc; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PacketType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.CrcMismatchException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPacketTypeException; /** * Created by andy on 6/1/18. @@ -29,7 +29,7 @@ public class OmnipodPacket implements RLMessage { throw new IllegalPacketTypeException(null, null); } this.sequenceNumber = (encoded[4] & 0b11111); - byte crc = OmniCRC.crc8(ByteUtil.substring(encoded, 0, encoded.length - 1)); + byte crc = OmnipodCrc.crc8(ByteUtil.substring(encoded, 0, encoded.length - 1)); if (crc != encoded[encoded.length - 1]) { throw new CrcMismatchException(crc, encoded[encoded.length - 1]); } @@ -70,7 +70,7 @@ public class OmnipodPacket implements RLMessage { output = ByteUtil.concat(output, ByteUtil.getBytesFromInt(this.packetAddress)); output = ByteUtil.concat(output, (byte) ((this.packetType.getValue() << 5) + (sequenceNumber & 0b11111))); output = ByteUtil.concat(output, encodedMessage); - output = ByteUtil.concat(output, OmniCRC.crc8(output)); + output = ByteUtil.concat(output, OmnipodCrc.crc8(output)); return output; } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/AcknowledgeAlertsCommand.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/AcknowledgeAlertsCommand.java similarity index 71% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/AcknowledgeAlertsCommand.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/AcknowledgeAlertsCommand.java index f429ed8b6f..b46ee8cc73 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/AcknowledgeAlertsCommand.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/AcknowledgeAlertsCommand.java @@ -1,12 +1,12 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command; import java.util.Collections; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.NonceResyncableMessageBlock; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSet; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSlot; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.MessageBlockType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.NonceResyncableMessageBlock; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertSet; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertSlot; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.MessageBlockType; public class AcknowledgeAlertsCommand extends NonceResyncableMessageBlock { diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/AssignAddressCommand.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/AssignAddressCommand.java similarity index 68% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/AssignAddressCommand.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/AssignAddressCommand.java index e7a942885c..4c0951e1b7 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/AssignAddressCommand.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/AssignAddressCommand.java @@ -1,9 +1,9 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command; import java.nio.ByteBuffer; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.MessageBlock; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.MessageBlockType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.MessageBlock; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.MessageBlockType; public class AssignAddressCommand extends MessageBlock { private final int address; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/BasalScheduleExtraCommand.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/BasalScheduleExtraCommand.java similarity index 89% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/BasalScheduleExtraCommand.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/BasalScheduleExtraCommand.java index 5d628537f9..8021fbfd8f 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/BasalScheduleExtraCommand.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/BasalScheduleExtraCommand.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command; import org.joda.time.Duration; @@ -6,11 +6,11 @@ import java.util.ArrayList; import java.util.List; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.MessageBlock; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.MessageBlockType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BasalSchedule; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.RateEntry; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.MessageBlock; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.MessageBlockType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalSchedule; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.RateEntry; public class BasalScheduleExtraCommand extends MessageBlock { private final boolean acknowledgementBeep; @@ -55,7 +55,7 @@ public class BasalScheduleExtraCommand extends MessageBlock { currentEntryIndex = (byte) entryLookupResult.getIndex(); double timeRemainingInEntryInSeconds = entryLookupResult.getStartTime().minus(scheduleOffsetNearestSecond.minus(entryLookupResult.getDuration())).getMillis() / 1000.0; double rate = mergedSchedule.rateAt(scheduleOffsetNearestSecond); - int pulsesPerHour = (int) Math.round(rate / OmnipodConst.POD_PULSE_SIZE); + int pulsesPerHour = (int) Math.round(rate / OmnipodConstants.POD_PULSE_SIZE); double timeBetweenPulses = 3600.0 / pulsesPerHour; delayUntilNextTenthOfPulseInSeconds = (timeRemainingInEntryInSeconds % (timeBetweenPulses / 10.0)); remainingPulses = pulsesPerHour * (timeRemainingInEntryInSeconds - delayUntilNextTenthOfPulseInSeconds) / 3600.0 + 0.1; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/BeepConfigCommand.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/BeepConfigCommand.java similarity index 87% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/BeepConfigCommand.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/BeepConfigCommand.java index 9695548f85..fc36e68eab 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/BeepConfigCommand.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/BeepConfigCommand.java @@ -1,11 +1,11 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command; import org.joda.time.Duration; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.MessageBlock; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.BeepConfigType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.MessageBlockType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.MessageBlock; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.BeepConfigType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.MessageBlockType; public class BeepConfigCommand extends MessageBlock { private final BeepConfigType beepType; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/BolusExtraCommand.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/BolusExtraCommand.java similarity index 86% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/BolusExtraCommand.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/BolusExtraCommand.java index a19b8b7651..465d1dee13 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/BolusExtraCommand.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/BolusExtraCommand.java @@ -1,12 +1,12 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command; import org.joda.time.Duration; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.CommandInitializationException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.MessageBlock; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.MessageBlockType; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.MessageBlock; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.MessageBlockType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.CommandInitializationException; public class BolusExtraCommand extends MessageBlock { private final boolean acknowledgementBeep; @@ -30,7 +30,7 @@ public class BolusExtraCommand extends MessageBlock { Duration programReminderInterval, Duration timeBetweenPulses) { if (units <= 0D) { throw new CommandInitializationException("Units should be > 0"); - } else if (units > OmnipodConst.MAX_BOLUS) { + } else if (units > OmnipodConstants.MAX_BOLUS) { throw new CommandInitializationException("Units exceeds max bolus"); } this.units = units; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/CancelDeliveryCommand.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/CancelDeliveryCommand.java similarity index 79% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/CancelDeliveryCommand.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/CancelDeliveryCommand.java index 451f9205f6..71eb4084d4 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/CancelDeliveryCommand.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/CancelDeliveryCommand.java @@ -1,12 +1,12 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command; import java.util.EnumSet; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.NonceResyncableMessageBlock; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.BeepType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.DeliveryType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.MessageBlockType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.NonceResyncableMessageBlock; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.BeepType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.MessageBlockType; public class CancelDeliveryCommand extends NonceResyncableMessageBlock { diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/ConfigureAlertsCommand.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/ConfigureAlertsCommand.java similarity index 74% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/ConfigureAlertsCommand.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/ConfigureAlertsCommand.java index ac0a6a9f67..f247174a45 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/ConfigureAlertsCommand.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/ConfigureAlertsCommand.java @@ -1,11 +1,11 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command; import java.util.List; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.NonceResyncableMessageBlock; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertConfiguration; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.MessageBlockType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.NonceResyncableMessageBlock; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertConfiguration; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.MessageBlockType; public class ConfigureAlertsCommand extends NonceResyncableMessageBlock { private final List configurations; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/DeactivatePodCommand.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/DeactivatePodCommand.java similarity index 72% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/DeactivatePodCommand.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/DeactivatePodCommand.java index 554d778d14..67f50d0587 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/DeactivatePodCommand.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/DeactivatePodCommand.java @@ -1,8 +1,8 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.NonceResyncableMessageBlock; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.MessageBlockType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.NonceResyncableMessageBlock; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.MessageBlockType; public class DeactivatePodCommand extends NonceResyncableMessageBlock { private int nonce; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/FaultConfigCommand.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/FaultConfigCommand.java similarity index 79% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/FaultConfigCommand.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/FaultConfigCommand.java index 9d165583e3..d09ce97702 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/FaultConfigCommand.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/FaultConfigCommand.java @@ -1,8 +1,8 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.NonceResyncableMessageBlock; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.MessageBlockType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.NonceResyncableMessageBlock; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.MessageBlockType; public class FaultConfigCommand extends NonceResyncableMessageBlock { private final byte tab5sub16; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/GetStatusCommand.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/GetStatusCommand.java similarity index 60% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/GetStatusCommand.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/GetStatusCommand.java index 68af71e277..d8664e4145 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/GetStatusCommand.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/GetStatusCommand.java @@ -1,8 +1,8 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.MessageBlock; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.MessageBlockType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.MessageBlock; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.MessageBlockType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType; public class GetStatusCommand extends MessageBlock { private final PodInfoType podInfoType; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/SetInsulinScheduleCommand.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/SetInsulinScheduleCommand.java similarity index 68% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/SetInsulinScheduleCommand.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/SetInsulinScheduleCommand.java index bebca2e7d7..88ad5d206d 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/SetInsulinScheduleCommand.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/SetInsulinScheduleCommand.java @@ -1,18 +1,18 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command; import org.joda.time.Duration; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.CommandInitializationException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.NonceResyncableMessageBlock; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.MessageBlockType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BasalDeliverySchedule; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BasalDeliveryTable; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BasalSchedule; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BolusDeliverySchedule; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.DeliverySchedule; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.TempBasalDeliverySchedule; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.NonceResyncableMessageBlock; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.MessageBlockType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalDeliverySchedule; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalDeliveryTable; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalSchedule; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BolusDeliverySchedule; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.DeliverySchedule; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.TempBasalDeliverySchedule; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.CommandInitializationException; public class SetInsulinScheduleCommand extends NonceResyncableMessageBlock { @@ -37,7 +37,7 @@ public class SetInsulinScheduleCommand extends NonceResyncableMessageBlock { int timeRemainingInSegment = BasalDeliveryTable.SEGMENT_DURATION - segmentOffset; - double timeBetweenPulses = 3600 / (rate / OmnipodConst.POD_PULSE_SIZE); + double timeBetweenPulses = 3600 / (rate / OmnipodConstants.POD_PULSE_SIZE); double offsetToNextTenth = timeRemainingInSegment % (timeBetweenPulses / 10.0); @@ -52,13 +52,13 @@ public class SetInsulinScheduleCommand extends NonceResyncableMessageBlock { public SetInsulinScheduleCommand(int nonce, double tempBasalRate, Duration duration) { if (tempBasalRate < 0D) { throw new CommandInitializationException("Rate should be >= 0"); - } else if (tempBasalRate > OmnipodConst.MAX_BASAL_RATE) { + } else if (tempBasalRate > OmnipodConstants.MAX_BASAL_RATE) { throw new CommandInitializationException("Rate exceeds max basal rate"); } - if (duration.isLongerThan(OmnipodConst.MAX_TEMP_BASAL_DURATION)) { + if (duration.isLongerThan(OmnipodConstants.MAX_TEMP_BASAL_DURATION)) { throw new CommandInitializationException("Duration exceeds max temp basal duration"); } - int pulsesPerHour = (int) Math.round(tempBasalRate / OmnipodConst.POD_PULSE_SIZE); + int pulsesPerHour = (int) Math.round(tempBasalRate / OmnipodConstants.POD_PULSE_SIZE); int pulsesPerSegment = pulsesPerHour / 2; this.nonce = nonce; this.schedule = new TempBasalDeliverySchedule(BasalDeliveryTable.SEGMENT_DURATION, pulsesPerSegment, new BasalDeliveryTable(tempBasalRate, duration)); diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/SetupPodCommand.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/SetupPodCommand.java similarity index 85% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/SetupPodCommand.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/SetupPodCommand.java index 7ef667d5b6..da383db564 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/SetupPodCommand.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/SetupPodCommand.java @@ -1,10 +1,10 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command; import org.joda.time.DateTime; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.MessageBlock; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.MessageBlockType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.MessageBlock; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.MessageBlockType; public class SetupPodCommand extends MessageBlock { diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/TempBasalExtraCommand.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/TempBasalExtraCommand.java similarity index 83% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/TempBasalExtraCommand.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/TempBasalExtraCommand.java index e076750399..031b36af71 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/command/TempBasalExtraCommand.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/TempBasalExtraCommand.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command; import org.joda.time.Duration; @@ -6,11 +6,11 @@ import java.util.ArrayList; import java.util.List; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.CommandInitializationException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.MessageBlock; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.MessageBlockType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.RateEntry; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.MessageBlock; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.MessageBlockType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.RateEntry; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.CommandInitializationException; public class TempBasalExtraCommand extends MessageBlock { private final boolean acknowledgementBeep; @@ -25,10 +25,10 @@ public class TempBasalExtraCommand extends MessageBlock { Duration programReminderInterval) { if (rate < 0D) { throw new CommandInitializationException("Rate should be >= 0"); - } else if (rate > OmnipodConst.MAX_BASAL_RATE) { + } else if (rate > OmnipodConstants.MAX_BASAL_RATE) { throw new CommandInitializationException("Rate exceeds max basal rate"); } - if (duration.isLongerThan(OmnipodConst.MAX_TEMP_BASAL_DURATION)) { + if (duration.isLongerThan(OmnipodConstants.MAX_TEMP_BASAL_DURATION)) { throw new CommandInitializationException("Duration exceeds max temp basal duration"); } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/ErrorResponse.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/ErrorResponse.java similarity index 80% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/ErrorResponse.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/ErrorResponse.java index 009baaeee4..2ef230ba2f 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/ErrorResponse.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/ErrorResponse.java @@ -1,10 +1,10 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.MessageBlock; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.FaultEventCode; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.MessageBlockType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodProgressStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.MessageBlock; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.FaultEventCode; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.MessageBlockType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; public class ErrorResponse extends MessageBlock { public static final byte ERROR_RESPONSE_CODE_BAD_NONCE = (byte) 0x14; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/StatusResponse.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/StatusResponse.java similarity index 56% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/StatusResponse.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/StatusResponse.java index 3837bd833b..5976d80a97 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/StatusResponse.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/StatusResponse.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response; import org.joda.time.Duration; @@ -6,14 +6,14 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.MessageBlock; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSet; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.DeliveryStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.MessageBlockType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodProgressStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.MessageBlock; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertSet; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.MessageBlockType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; -public class StatusResponse extends MessageBlock { +public class StatusResponse extends MessageBlock implements StatusUpdatableResponse { private static final int MESSAGE_LENGTH = 10; private final DeliveryStatus deliveryStatus; @@ -22,9 +22,9 @@ public class StatusResponse extends MessageBlock { private final Double reservoirLevel; private final int ticksDelivered; private final double insulinDelivered; - private final double insulinNotDelivered; + private final double bolusNotDelivered; private final byte podMessageCounter; - private final AlertSet alerts; + private final AlertSet unacknowledgedAlerts; public StatusResponse(byte[] encodedData) { if (encodedData.length < MESSAGE_LENGTH) { @@ -42,14 +42,14 @@ public class StatusResponse extends MessageBlock { int middleInsulinBits = ByteUtil.convertUnsignedByteToInt(encodedData[3]) << 1; int lowInsulinBits = ByteUtil.convertUnsignedByteToInt(encodedData[4]) >>> 7; ticksDelivered = (highInsulinBits | middleInsulinBits | lowInsulinBits); - insulinDelivered = OmnipodConst.POD_PULSE_SIZE * ticksDelivered; + insulinDelivered = OmnipodConstants.POD_PULSE_SIZE * ticksDelivered; podMessageCounter = (byte) ((encodedData[4] >>> 3) & 0xf); - insulinNotDelivered = OmnipodConst.POD_PULSE_SIZE * (((encodedData[4] & 0x03) << 8) | ByteUtil.convertUnsignedByteToInt(encodedData[5])); - alerts = new AlertSet((byte) (((encodedData[6] & 0x7f) << 1) | (ByteUtil.convertUnsignedByteToInt(encodedData[7]) >>> 7))); + bolusNotDelivered = OmnipodConstants.POD_PULSE_SIZE * (((encodedData[4] & 0x03) << 8) | ByteUtil.convertUnsignedByteToInt(encodedData[5])); + unacknowledgedAlerts = new AlertSet((byte) (((encodedData[6] & 0x7f) << 1) | (ByteUtil.convertUnsignedByteToInt(encodedData[7]) >>> 7))); - double reservoirValue = (((encodedData[8] & 0x3) << 8) + ByteUtil.convertUnsignedByteToInt(encodedData[9])) * OmnipodConst.POD_PULSE_SIZE; - if (reservoirValue > OmnipodConst.MAX_RESERVOIR_READING) { + double reservoirValue = (((encodedData[8] & 0x3) << 8) + ByteUtil.convertUnsignedByteToInt(encodedData[9])) * OmnipodConstants.POD_PULSE_SIZE; + if (reservoirValue > OmnipodConstants.MAX_RESERVOIR_READING) { reservoirLevel = null; } else { reservoirLevel = reservoirValue; @@ -61,41 +61,43 @@ public class StatusResponse extends MessageBlock { return MessageBlockType.STATUS_RESPONSE; } - public DeliveryStatus getDeliveryStatus() { + @Override public DeliveryStatus getDeliveryStatus() { return deliveryStatus; } - public PodProgressStatus getPodProgressStatus() { + @Override public PodProgressStatus getPodProgressStatus() { return podProgressStatus; } - public Duration getTimeActive() { + @Override public Duration getTimeActive() { return timeActive; } - public Double getReservoirLevel() { + @Override public Double getReservoirLevel() { return reservoirLevel; } - public int getTicksDelivered() { return ticksDelivered; } + @Override public int getTicksDelivered() { + return ticksDelivered; + } - public double getInsulinDelivered() { + @Override public double getInsulinDelivered() { return insulinDelivered; } - public double getInsulinNotDelivered() { - return insulinNotDelivered; + @Override public double getBolusNotDelivered() { + return bolusNotDelivered; } - public byte getPodMessageCounter() { + @Override public byte getPodMessageCounter() { return podMessageCounter; } - public AlertSet getAlerts() { - return alerts; + @Override public AlertSet getUnacknowledgedAlerts() { + return unacknowledgedAlerts; } - public byte[] getRawData() { + @Override public byte[] getRawData() { ByteArrayOutputStream stream = new ByteArrayOutputStream(); try { stream.write(getType().getValue()); @@ -107,17 +109,18 @@ public class StatusResponse extends MessageBlock { return stream.toByteArray(); } - @Override - public String toString() { + @Override public String toString() { return "StatusResponse{" + "deliveryStatus=" + deliveryStatus + ", podProgressStatus=" + podProgressStatus + ", timeActive=" + timeActive + ", reservoirLevel=" + reservoirLevel + + ", ticksDelivered=" + ticksDelivered + ", insulinDelivered=" + insulinDelivered + - ", insulinNotDelivered=" + insulinNotDelivered + + ", bolusNotDelivered=" + bolusNotDelivered + ", podMessageCounter=" + podMessageCounter + - ", alerts=" + alerts + + ", unacknowledgedAlerts=" + unacknowledgedAlerts + + ", encodedData=" + ByteUtil.shortHexStringWithoutSpaces(encodedData) + '}'; } } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/StatusUpdatableResponse.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/StatusUpdatableResponse.java new file mode 100644 index 0000000000..4dee2127fc --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/StatusUpdatableResponse.java @@ -0,0 +1,27 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response; + +import org.joda.time.Duration; + +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertSet; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; + +public interface StatusUpdatableResponse { + DeliveryStatus getDeliveryStatus(); + + PodProgressStatus getPodProgressStatus(); + + Duration getTimeActive(); + + Double getReservoirLevel(); + + int getTicksDelivered(); + + double getInsulinDelivered(); + + double getBolusNotDelivered(); + + byte getPodMessageCounter(); + + AlertSet getUnacknowledgedAlerts(); +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/VersionResponse.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/VersionResponse.java similarity index 89% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/VersionResponse.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/VersionResponse.java index c62add6732..e406715d2d 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/VersionResponse.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/VersionResponse.java @@ -1,10 +1,10 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.MessageBlock; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.FirmwareVersion; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.MessageBlockType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodProgressStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.MessageBlock; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.FirmwareVersion; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.MessageBlockType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; public class VersionResponse extends MessageBlock { private static final int ASSIGN_ADDRESS_VERSION_RESPONSE_LENGTH = 0x15; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/podinfo/PodInfo.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfo.java similarity index 51% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/podinfo/PodInfo.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfo.java index 9002f0d92e..4a65b678cb 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/podinfo/PodInfo.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfo.java @@ -1,11 +1,11 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType; public abstract class PodInfo { private final byte[] encodedData; - public PodInfo(byte[] encodedData) { + PodInfo(byte[] encodedData) { this.encodedData = encodedData; } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/podinfo/PodInfoActiveAlerts.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoActiveAlerts.java similarity index 85% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/podinfo/PodInfoActiveAlerts.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoActiveAlerts.java index 1f32777fda..6723a0a0da 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/podinfo/PodInfoActiveAlerts.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoActiveAlerts.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo; import org.joda.time.Duration; @@ -7,9 +7,9 @@ import java.util.Arrays; import java.util.List; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSlot; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertSlot; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType; public class PodInfoActiveAlerts extends PodInfo { private static final int MINIMUM_MESSAGE_LENGTH = 11; @@ -69,7 +69,7 @@ public class PodInfoActiveAlerts extends PodInfo { } public double getValueAsUnits() { - return value * OmnipodConst.POD_PULSE_SIZE; + return value * OmnipodConstants.POD_PULSE_SIZE; } public Duration getValueAsDuration() { diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/podinfo/PodInfoDataLog.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoDataLog.java similarity index 89% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/podinfo/PodInfoDataLog.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoDataLog.java index b8e28169d3..0151a761af 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/podinfo/PodInfoDataLog.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoDataLog.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo; import org.joda.time.Duration; @@ -7,8 +7,8 @@ import java.util.Collections; import java.util.List; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.FaultEventCode; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.FaultEventCode; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType; public class PodInfoDataLog extends PodInfo { private static final int MINIMUM_MESSAGE_LENGTH = 8; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/podinfo/PodInfoFaultAndInitializationTime.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultAndInitializationTime.java similarity index 86% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/podinfo/PodInfoFaultAndInitializationTime.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultAndInitializationTime.java index 2fd1d90406..f96b00b909 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/podinfo/PodInfoFaultAndInitializationTime.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultAndInitializationTime.java @@ -1,10 +1,10 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo; import org.joda.time.DateTime; import org.joda.time.Duration; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.FaultEventCode; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.FaultEventCode; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType; public class PodInfoFaultAndInitializationTime extends PodInfo { private static final int MINIMUM_MESSAGE_LENGTH = 17; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/podinfo/PodInfoFaultEvent.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultEvent.java similarity index 66% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/podinfo/PodInfoFaultEvent.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultEvent.java index 129ef989bb..d099894ab6 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/podinfo/PodInfoFaultEvent.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultEvent.java @@ -1,28 +1,30 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo; import org.joda.time.Duration; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSet; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.DeliveryStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.FaultEventCode; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.LogEventErrorCode; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodProgressStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusUpdatableResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertSet; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.FaultEventCode; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.LogEventErrorCode; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; -public class PodInfoFaultEvent extends PodInfo { +public class PodInfoFaultEvent extends PodInfo implements StatusUpdatableResponse { private static final int MINIMUM_MESSAGE_LENGTH = 21; private final PodProgressStatus podProgressStatus; private final DeliveryStatus deliveryStatus; - private final double insulinNotDelivered; + private final double bolusNotDelivered; private final byte podMessageCounter; - private final double totalInsulinDelivered; + private final int ticksDelivered; + private final double insulinDelivered; private final FaultEventCode faultEventCode; private final Duration faultEventTime; private final Double reservoirLevel; - private final Duration timeSinceActivation; + private final Duration timeActive; private final AlertSet unacknowledgedAlerts; private final boolean faultAccessingTables; private final LogEventErrorCode logEventErrorType; @@ -41,9 +43,10 @@ public class PodInfoFaultEvent extends PodInfo { podProgressStatus = PodProgressStatus.fromByte(encodedData[1]); deliveryStatus = DeliveryStatus.fromByte(encodedData[2]); - insulinNotDelivered = OmnipodConst.POD_PULSE_SIZE * ByteUtil.toInt(encodedData[3], encodedData[4]); + bolusNotDelivered = OmnipodConstants.POD_PULSE_SIZE * ByteUtil.toInt(encodedData[3], encodedData[4]); podMessageCounter = encodedData[5]; - totalInsulinDelivered = OmnipodConst.POD_PULSE_SIZE * ByteUtil.toInt(encodedData[6], encodedData[7]); + ticksDelivered = ByteUtil.toInt(encodedData[6], encodedData[7]); + insulinDelivered = OmnipodConstants.POD_PULSE_SIZE * ticksDelivered; faultEventCode = FaultEventCode.fromByte(encodedData[8]); int minutesSinceActivation = ByteUtil.toInt(encodedData[9], encodedData[10]); @@ -54,15 +57,15 @@ public class PodInfoFaultEvent extends PodInfo { } double reservoirValue = ((encodedData[11] & 0x03) << 8) + - ByteUtil.convertUnsignedByteToInt(encodedData[12]) * OmnipodConst.POD_PULSE_SIZE; - if (reservoirValue > OmnipodConst.MAX_RESERVOIR_READING) { + ByteUtil.convertUnsignedByteToInt(encodedData[12]) * OmnipodConstants.POD_PULSE_SIZE; + if (reservoirValue > OmnipodConstants.MAX_RESERVOIR_READING) { reservoirLevel = null; } else { reservoirLevel = reservoirValue; } int minutesActive = ByteUtil.toInt(encodedData[13], encodedData[14]); - timeSinceActivation = Duration.standardMinutes(minutesActive); + timeActive = Duration.standardMinutes(minutesActive); unacknowledgedAlerts = new AlertSet(encodedData[15]); faultAccessingTables = encodedData[16] == 0x02; @@ -79,24 +82,28 @@ public class PodInfoFaultEvent extends PodInfo { return PodInfoType.FAULT_EVENT; } - public PodProgressStatus getPodProgressStatus() { + @Override public PodProgressStatus getPodProgressStatus() { return podProgressStatus; } - public DeliveryStatus getDeliveryStatus() { + @Override public DeliveryStatus getDeliveryStatus() { return deliveryStatus; } - public double getInsulinNotDelivered() { - return insulinNotDelivered; + @Override public double getBolusNotDelivered() { + return bolusNotDelivered; } - public byte getPodMessageCounter() { + @Override public byte getPodMessageCounter() { return podMessageCounter; } - public double getTotalInsulinDelivered() { - return totalInsulinDelivered; + @Override public int getTicksDelivered() { + return ticksDelivered; + } + + @Override public double getInsulinDelivered() { + return insulinDelivered; } public FaultEventCode getFaultEventCode() { @@ -107,15 +114,15 @@ public class PodInfoFaultEvent extends PodInfo { return faultEventTime; } - public Double getReservoirLevel() { + @Override public Double getReservoirLevel() { return reservoirLevel; } - public Duration getTimeSinceActivation() { - return timeSinceActivation; + @Override public Duration getTimeActive() { + return timeActive; } - public AlertSet getUnacknowledgedAlerts() { + @Override public AlertSet getUnacknowledgedAlerts() { return unacknowledgedAlerts; } @@ -147,18 +154,18 @@ public class PodInfoFaultEvent extends PodInfo { return unknownValue; } - @Override - public String toString() { + @Override public String toString() { return "PodInfoFaultEvent{" + "podProgressStatus=" + podProgressStatus + ", deliveryStatus=" + deliveryStatus + - ", insulinNotDelivered=" + insulinNotDelivered + + ", bolusNotDelivered=" + bolusNotDelivered + ", podMessageCounter=" + podMessageCounter + - ", totalInsulinDelivered=" + totalInsulinDelivered + + ", ticksDelivered=" + ticksDelivered + + ", insulinDelivered=" + insulinDelivered + ", faultEventCode=" + faultEventCode + ", faultEventTime=" + faultEventTime + ", reservoirLevel=" + reservoirLevel + - ", timeSinceActivation=" + timeSinceActivation + + ", timeActive=" + timeActive + ", unacknowledgedAlerts=" + unacknowledgedAlerts + ", faultAccessingTables=" + faultAccessingTables + ", logEventErrorType=" + logEventErrorType + diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/podinfo/PodInfoOlderPulseLog.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoOlderPulseLog.java similarity index 88% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/podinfo/PodInfoOlderPulseLog.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoOlderPulseLog.java index c36b053cce..ae10eca820 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/podinfo/PodInfoOlderPulseLog.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoOlderPulseLog.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo; import android.text.TextUtils; @@ -7,7 +7,7 @@ import java.util.Collections; import java.util.List; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType; public class PodInfoOlderPulseLog extends PodInfo { private static final int MINIMUM_MESSAGE_LENGTH = 3; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/podinfo/PodInfoRecentPulseLog.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoRecentPulseLog.java similarity index 89% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/podinfo/PodInfoRecentPulseLog.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoRecentPulseLog.java index 1008cca689..00527a74f1 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/podinfo/PodInfoRecentPulseLog.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoRecentPulseLog.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo; import android.text.TextUtils; @@ -7,7 +7,7 @@ import java.util.Collections; import java.util.List; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType; public class PodInfoRecentPulseLog extends PodInfo { private static final int MINIMUM_MESSAGE_LENGTH = 3; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/podinfo/PodInfoResponse.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoResponse.java similarity index 67% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/podinfo/PodInfoResponse.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoResponse.java index 59322f6209..cee243c45f 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/message/response/podinfo/PodInfoResponse.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoResponse.java @@ -1,9 +1,9 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.MessageBlock; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.MessageBlockType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.MessageBlock; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.MessageBlockType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType; public class PodInfoResponse extends MessageBlock { private final PodInfoType subType; @@ -21,8 +21,8 @@ public class PodInfoResponse extends MessageBlock { return subType; } - public T getPodInfo() { - return (T) podInfo; + public PodInfo getPodInfo() { + return podInfo; } @Override diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/db/PodHistoryEntryType.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/db/PodHistoryEntryType.java deleted file mode 100644 index 351a845e8d..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/db/PodHistoryEntryType.java +++ /dev/null @@ -1,92 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.driver.db; - -import androidx.annotation.StringRes; - -import java.util.HashMap; -import java.util.Map; - -import info.nightscout.androidaps.plugins.pump.common.defs.PumpHistoryEntryGroup; -import info.nightscout.androidaps.plugins.pump.omnipod.R; - -/** - * Created by andy on 24.11.2019 - */ -public enum PodHistoryEntryType { - - PairAndPrime(1, R.string.omnipod_init_pod_wizard_step2_title, PumpHistoryEntryGroup.Prime), - FillCannulaSetBasalProfile(2, R.string.omnipod_init_pod_wizard_step4_title, PumpHistoryEntryGroup.Prime), - DeactivatePod(3, R.string.omnipod_cmd_deactivate_pod, PumpHistoryEntryGroup.Prime), - ResetPodState(4, R.string.omnipod_cmd_reset_pod, PumpHistoryEntryGroup.Prime), - - SetTemporaryBasal(10, R.string.omnipod_cmd_set_tbr, PumpHistoryEntryGroup.Basal), - CancelTemporaryBasal(11, R.string.omnipod_cmd_cancel_tbr, PumpHistoryEntryGroup.Basal), - CancelTemporaryBasalForce(12, R.string.omnipod_cmd_cancel_tbr_forced, PumpHistoryEntryGroup.Basal), - - SetBasalSchedule(20, R.string.omnipod_cmd_set_basal_schedule, PumpHistoryEntryGroup.Basal), - - GetPodStatus(30, R.string.omnipod_cmd_get_pod_status, PumpHistoryEntryGroup.Configuration), - GetPodInfo(31, R.string.omnipod_cmd_get_pod_info, PumpHistoryEntryGroup.Configuration), - SetTime(32, R.string.omnipod_cmd_set_time, PumpHistoryEntryGroup.Configuration), - - SetBolus(40, R.string.omnipod_cmd_set_bolus, PumpHistoryEntryGroup.Bolus), - CancelBolus(41, R.string.omnipod_cmd_cancel_bolus, PumpHistoryEntryGroup.Bolus), - - ConfigureAlerts(50, R.string.omnipod_cmd_configure_alerts, PumpHistoryEntryGroup.Alarm), - AcknowledgeAlerts(51, R.string.omnipod_cmd_acknowledge_alerts, PumpHistoryEntryGroup.Alarm), - - SuspendDelivery(60, R.string.omnipod_cmd_suspend_delivery, PumpHistoryEntryGroup.Basal), - ResumeDelivery(61, R.string.omnipod_cmd_resume_delivery, PumpHistoryEntryGroup.Basal), - - UnknownEntryType(99, R.string.omnipod_cmd_unknown_entry); - - private int code; - private static Map instanceMap; - - @StringRes - private int resourceId; - - private PumpHistoryEntryGroup group; - - static { - instanceMap = new HashMap<>(); - - for (PodHistoryEntryType value : values()) { - instanceMap.put(value.code, value); - } - } - - PodHistoryEntryType(int code, @StringRes int resourceId) { - this.code = code; - this.resourceId = resourceId; - } - - PodHistoryEntryType(int code, @StringRes int resourceId, PumpHistoryEntryGroup group) { - this.code = code; - this.resourceId = resourceId; - this.group = group; - } - - public int getCode() { - return code; - } - - public PumpHistoryEntryGroup getGroup() { - return this.group; - } - - public static PodHistoryEntryType getByCode(long code) { - return getByCode((int) code); - } - - public static PodHistoryEntryType getByCode(int code) { - if (instanceMap.containsKey(code)) { - return instanceMap.get(code); - } else { - return UnknownEntryType; - } - } - - public int getResourceId() { - return resourceId; - } -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/AlertConfiguration.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/AlertConfiguration.java similarity index 71% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/AlertConfiguration.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/AlertConfiguration.java index 6c48954cfe..ab72fe323f 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/AlertConfiguration.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/AlertConfiguration.java @@ -1,9 +1,8 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; import org.joda.time.Duration; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; public class AlertConfiguration { private final AlertType alertType; @@ -16,8 +15,7 @@ public class AlertConfiguration { private final BeepType beepType; public AlertConfiguration(AlertType alertType, AlertSlot alertSlot, boolean active, boolean autoOffModifier, - Duration duration, AlertTrigger alertTrigger, - BeepType beepType, BeepRepeat beepRepeat) { + Duration duration, AlertTrigger alertTrigger, BeepType beepType, BeepRepeat beepRepeat) { this.alertType = alertType; this.alertSlot = alertSlot; this.active = active; @@ -36,6 +34,14 @@ public class AlertConfiguration { return alertSlot; } + public AlertTrigger getAlertTrigger() { + return alertTrigger; + } + + public boolean isActive() { + return active; + } + public byte[] getRawData() { int firstByte = (alertSlot.getValue() << 4); firstByte += active ? (1 << 3) : 0; @@ -56,7 +62,7 @@ public class AlertConfiguration { }; if (alertTrigger instanceof UnitsRemainingAlertTrigger) { - int ticks = (int) (((UnitsRemainingAlertTrigger) alertTrigger).getValue() / OmnipodConst.POD_PULSE_SIZE / 2); + int ticks = (int) (((UnitsRemainingAlertTrigger) alertTrigger).getValue() / OmnipodConstants.POD_PULSE_SIZE / 2); encodedData = ByteUtil.concat(encodedData, ByteUtil.getBytesFromInt16(ticks)); } else if (alertTrigger instanceof TimerAlertTrigger) { int durationInMinutes = (int) ((TimerAlertTrigger) alertTrigger).getValue().getStandardMinutes(); @@ -68,4 +74,17 @@ public class AlertConfiguration { return encodedData; } + + @Override public String toString() { + return "AlertConfiguration{" + + "alertType=" + alertType + + ", alertSlot=" + alertSlot + + ", active=" + active + + ", autoOffModifier=" + autoOffModifier + + ", duration=" + duration + + ", alertTrigger=" + alertTrigger + + ", beepRepeat=" + beepRepeat + + ", beepType=" + beepType + + '}'; + } } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/AlertSet.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/AlertSet.java similarity index 94% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/AlertSet.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/AlertSet.java index 91590e2f12..c9d61f9172 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/AlertSet.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/AlertSet.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; import java.util.ArrayList; import java.util.List; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/AlertSlot.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/AlertSlot.java similarity index 86% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/AlertSlot.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/AlertSlot.java index 9f76ae0983..194f5f940b 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/AlertSlot.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/AlertSlot.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; public enum AlertSlot { SLOT0((byte) 0x00), @@ -10,7 +10,7 @@ public enum AlertSlot { SLOT6((byte) 0x06), SLOT7((byte) 0x07); - private byte value; + private final byte value; AlertSlot(byte value) { this.value = value; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/AlertTrigger.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/AlertTrigger.java new file mode 100644 index 0000000000..533c465919 --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/AlertTrigger.java @@ -0,0 +1,19 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; + +public abstract class AlertTrigger { + private final T value; + + AlertTrigger(T value) { + this.value = value; + } + + public T getValue() { + return value; + } + + @Override public String toString() { + return "AlertTrigger{" + + "value=" + value + + '}'; + } +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/AlertType.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/AlertType.java similarity index 73% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/AlertType.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/AlertType.java index eb4b068a6f..e6cd161eb1 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/AlertType.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/AlertType.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; public enum AlertType { FINISH_PAIRING_REMINDER, diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/BeepConfigType.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/BeepConfigType.java similarity index 91% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/BeepConfigType.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/BeepConfigType.java index 3ef731e5c8..00f91a0af7 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/BeepConfigType.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/BeepConfigType.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; // BeepConfigType is used only for the $1E Beep Config Command. @@ -19,7 +19,7 @@ public enum BeepConfigType { FIVE_SECONDS_BEEP((byte) 0xE), // can only be used if Pod is currently suspended NO_BEEP((byte) 0xF); - private byte value; + private final byte value; BeepConfigType(byte value) { this.value = value; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/BeepRepeat.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/BeepRepeat.java similarity index 83% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/BeepRepeat.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/BeepRepeat.java index 3562dd6c18..3cf34bc247 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/BeepRepeat.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/BeepRepeat.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; public enum BeepRepeat { ONCE((byte) 0x00), @@ -11,7 +11,7 @@ public enum BeepRepeat { EVERY_15_MINUTES_DELAYED((byte) 0x07), EVERY_5_MINUTES((byte) 0x08); - private byte value; + private final byte value; BeepRepeat(byte value) { this.value = value; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/BeepType.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/BeepType.java similarity index 88% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/BeepType.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/BeepType.java index e230276467..17bbc855b2 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/BeepType.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/BeepType.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; // BeepType is used for the $19 Configure Alerts and $1F Cancel Commands public enum BeepType { @@ -12,7 +12,7 @@ public enum BeepType { BIP_BIP_BIP_BIP_BIP_BIP((byte) 0x07), BEEEP_BEEEP((byte) 0x08); - private byte value; + private final byte value; BeepType(byte value) { this.value = value; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/DeliveryStatus.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/DeliveryStatus.java similarity index 76% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/DeliveryStatus.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/DeliveryStatus.java index 9df1d480a5..5987cb69a0 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/DeliveryStatus.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/DeliveryStatus.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; public enum DeliveryStatus { SUSPENDED((byte) 0x00), @@ -8,7 +8,7 @@ public enum DeliveryStatus { BOLUS_IN_PROGRESS((byte) 0x05), BOLUS_AND_TEMP_BASAL((byte) 0x06); - private byte value; + private final byte value; DeliveryStatus(byte value) { this.value = value; @@ -30,4 +30,8 @@ public enum DeliveryStatus { public boolean isBolusing() { return this.equals(BOLUS_IN_PROGRESS) || this.equals(BOLUS_AND_TEMP_BASAL); } + + public boolean isTbrRunning() { + return this.equals(TEMP_BASAL_RUNNING) || this.equals(BOLUS_AND_TEMP_BASAL); + } } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/DeliveryType.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/DeliveryType.java similarity index 83% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/DeliveryType.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/DeliveryType.java index 4d595afc15..b0e80105f4 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/DeliveryType.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/DeliveryType.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; public enum DeliveryType { NONE((byte) 0x00), @@ -6,7 +6,7 @@ public enum DeliveryType { TEMP_BASAL((byte) 0x02), BOLUS((byte) 0x04); - private byte value; + private final byte value; DeliveryType(byte value) { this.value = value; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/FaultEventCode.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/FaultEventCode.java similarity index 98% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/FaultEventCode.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/FaultEventCode.java index df17fd0b5c..a6fac508db 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/FaultEventCode.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/FaultEventCode.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; import java.util.Locale; @@ -122,7 +122,7 @@ public enum FaultEventCode { BAD_STATE_IN_MAYBE_INC_33_D((byte) 0x97), VALUES_DO_NOT_MATCH_OR_ARE_GREATER_THAN_0_X_97((byte) 0x98); - private byte value; + private final byte value; FaultEventCode(byte value) { this.value = value; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/FirmwareVersion.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/FirmwareVersion.java similarity index 89% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/FirmwareVersion.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/FirmwareVersion.java index 27dab2c091..a4ed7e2eea 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/FirmwareVersion.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/FirmwareVersion.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; import java.util.Locale; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/LogEventErrorCode.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/LogEventErrorCode.java similarity index 86% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/LogEventErrorCode.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/LogEventErrorCode.java index 1cf366fd61..eb7223b4f0 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/LogEventErrorCode.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/LogEventErrorCode.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; public enum LogEventErrorCode { NONE((byte) 0x00), @@ -7,7 +7,7 @@ public enum LogEventErrorCode { INTERNAL_2_BIT_VARIABLE_SET_AND_MANIPULATED_IN_MAIN_LOOP_ROUTINES_3((byte) 0x03), INSULIN_STATE_TABLE_CORRUPTION((byte) 0x04); - private byte value; + private final byte value; LogEventErrorCode(byte value) { this.value = value; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/MessageBlockType.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/MessageBlockType.java similarity index 69% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/MessageBlockType.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/MessageBlockType.java index a7ced69305..16002aa343 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/MessageBlockType.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/MessageBlockType.java @@ -1,12 +1,12 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; import org.apache.commons.lang3.NotImplementedException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.MessageBlock; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.ErrorResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.VersionResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.MessageBlock; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.ErrorResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.VersionResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoResponse; public enum MessageBlockType { VERSION_RESPONSE(0x01), @@ -27,7 +27,7 @@ public enum MessageBlockType { BEEP_CONFIG(0x1e), CANCEL_DELIVERY(0x1f); - private byte value; + private final byte value; MessageBlockType(int value) { this.value = (byte) value; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodConst.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/OmnipodConstants.java similarity index 50% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodConst.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/OmnipodConstants.java index a036571bf4..b36dc765c7 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodConst.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/OmnipodConstants.java @@ -1,37 +1,12 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.util; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; import org.joda.time.Duration; -import info.nightscout.androidaps.plugins.pump.omnipod.R; - /** * Created by andy on 4.8.2019 */ -public class OmnipodConst { - - static final String Prefix = "AAPS.Omnipod."; - - public static class Prefs { - public static final String PodState = Prefix + "pod_state"; - public static final String ActiveBolus = Prefix + "current_bolus"; - public static final int BeepBasalEnabled = R.string.key_omnipod_beep_basal_enabled; - public static final int BeepBolusEnabled = R.string.key_omnipod_beep_bolus_enabled; - public static final int BeepSMBEnabled = R.string.key_omnipod_beep_smb_enabled; - public static final int BeepTBREnabled = R.string.key_omnipod_beep_tbr_enabled; - public static final int PodDebuggingOptionsEnabled = R.string.key_omnipod_pod_debugging_options_enabled; - public static final int TimeChangeEventEnabled = R.string.key_omnipod_timechange_enabled; - } - - public static class Statistics { - public static final String StatsPrefix = "omnipod_"; - public static final String FirstPumpStart = Prefix + "first_pump_use"; - public static final String LastGoodPumpCommunicationTime = Prefix + "lastGoodPumpCommunicationTime"; - public static final String TBRsSet = StatsPrefix + "tbrs_set"; - public static final String StandardBoluses = StatsPrefix + "std_boluses_delivered"; - public static final String SMBBoluses = StatsPrefix + "smb_boluses_delivered"; - } - +public class OmnipodConstants { public static final double POD_PULSE_SIZE = 0.05; public static final double POD_BOLUS_DELIVERY_RATE = 0.025; // units per second public static final double POD_PRIMING_DELIVERY_RATE = 0.05; // units per second diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmniCRC.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/OmnipodCrc.java similarity index 96% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmniCRC.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/OmnipodCrc.java index 77d0cc1aad..ebc461ee9a 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmniCRC.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/OmnipodCrc.java @@ -1,6 +1,6 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.util; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; -public class OmniCRC { +public class OmnipodCrc { public static final int[] crc16lookup = new int[]{ 0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011, 0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022, @@ -35,7 +35,8 @@ public class OmniCRC { 0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231, 0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202 }; - public static final int[] crc8lookup = new int[]{ + + private static final int[] crc8lookup = new int[]{ 0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D, 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D, 0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5, 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD, @@ -54,7 +55,6 @@ public class OmniCRC { 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3 }; - public static int crc16(byte[] bytes) { int crc = 0x0000; for (byte b : bytes) { diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/PacketType.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/PacketType.java similarity index 88% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/PacketType.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/PacketType.java index aae862d9b8..cfc3bff947 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/PacketType.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/PacketType.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; public enum PacketType { INVALID((byte) 0), @@ -7,7 +7,7 @@ public enum PacketType { CON((byte) 0b100), ACK((byte) 0b010); - private byte value; + private final byte value; PacketType(byte value) { this.value = value; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/PodInfoType.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/PodInfoType.java similarity index 67% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/PodInfoType.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/PodInfoType.java index 4e2095e711..d85ee9bd3f 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/PodInfoType.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/PodInfoType.java @@ -1,12 +1,12 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfo; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoActiveAlerts; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoDataLog; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoFaultAndInitializationTime; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoFaultEvent; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoOlderPulseLog; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoRecentPulseLog; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfo; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoActiveAlerts; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoDataLog; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoFaultAndInitializationTime; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoFaultEvent; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoOlderPulseLog; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoRecentPulseLog; public enum PodInfoType { NORMAL((byte) 0x00), diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/PodProgressStatus.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/PodProgressStatus.java similarity index 94% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/PodProgressStatus.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/PodProgressStatus.java index 0c89981601..9da2916997 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/PodProgressStatus.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/PodProgressStatus.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; public enum PodProgressStatus { INITIALIZED((byte) 0x00), @@ -18,7 +18,7 @@ public enum PodProgressStatus { ACTIVATION_TIME_EXCEEDED((byte) 0x0e), // Took > 2 hours from progress 2 to 3 or > 1 hour from 3 to 8 INACTIVE((byte) 0x0f); // Pod deactivated or a fatal packet state error - private byte value; + private final byte value; PodProgressStatus(byte value) { this.value = value; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/TimerAlertTrigger.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/TimerAlertTrigger.java similarity index 69% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/TimerAlertTrigger.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/TimerAlertTrigger.java index 8d4096de59..5344d736b2 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/TimerAlertTrigger.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/TimerAlertTrigger.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; import org.joda.time.Duration; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/UnitsRemainingAlertTrigger.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/UnitsRemainingAlertTrigger.java similarity index 67% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/UnitsRemainingAlertTrigger.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/UnitsRemainingAlertTrigger.java index 6668be13c8..fd0fb4bae4 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/UnitsRemainingAlertTrigger.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/UnitsRemainingAlertTrigger.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; public class UnitsRemainingAlertTrigger extends AlertTrigger { public UnitsRemainingAlertTrigger(Double value) { diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/BasalDeliverySchedule.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/BasalDeliverySchedule.java similarity index 91% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/BasalDeliverySchedule.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/BasalDeliverySchedule.java index ab46dacd76..497b41e1b6 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/BasalDeliverySchedule.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/BasalDeliverySchedule.java @@ -1,7 +1,7 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.IRawRepresentable; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.IRawRepresentable; public class BasalDeliverySchedule extends DeliverySchedule implements IRawRepresentable { diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/BasalDeliveryTable.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/BasalDeliveryTable.java similarity index 88% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/BasalDeliveryTable.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/BasalDeliveryTable.java index 3e18d6b5d0..df1c4161ec 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/BasalDeliveryTable.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/BasalDeliveryTable.java @@ -1,11 +1,11 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule; import org.joda.time.Duration; import java.util.ArrayList; import java.util.List; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; public class BasalDeliveryTable { @@ -15,7 +15,7 @@ public class BasalDeliveryTable { private static final int NUM_SEGMENTS = 48; private static final int MAX_SEGMENTS_PER_ENTRY = 16; - private List entries = new ArrayList<>(); + private final List entries = new ArrayList<>(); public BasalDeliveryTable(BasalSchedule schedule) { TempSegment[] expandedSegments = new TempSegment[48]; @@ -23,7 +23,7 @@ public class BasalDeliveryTable { boolean halfPulseRemainder = false; for (int i = 0; i < NUM_SEGMENTS; i++) { double rate = schedule.rateAt(Duration.standardMinutes(i * 30)); - int pulsesPerHour = (int) Math.round(rate / OmnipodConst.POD_PULSE_SIZE); + int pulsesPerHour = (int) Math.round(rate / OmnipodConstants.POD_PULSE_SIZE); int pulsesPerSegment = pulsesPerHour >>> 1; boolean halfPulse = (pulsesPerHour & 0b1) != 0; @@ -61,7 +61,7 @@ public class BasalDeliveryTable { } public BasalDeliveryTable(double tempBasalRate, Duration duration) { - int pulsesPerHour = (int) Math.round(tempBasalRate / OmnipodConst.POD_PULSE_SIZE); + int pulsesPerHour = (int) Math.round(tempBasalRate / OmnipodConstants.POD_PULSE_SIZE); int pulsesPerSegment = pulsesPerHour >> 1; boolean alternateSegmentPulse = (pulsesPerHour & 0b1) != 0; @@ -97,14 +97,14 @@ public class BasalDeliveryTable { '}'; } - private class TempSegment { - private int pulses; + private static class TempSegment { + private final int pulses; - public TempSegment(int pulses) { + TempSegment(int pulses) { this.pulses = pulses; } - public int getPulses() { + int getPulses() { return pulses; } } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/BasalSchedule.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/BasalSchedule.java similarity index 85% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/BasalSchedule.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/BasalSchedule.java index 140c584c0b..24f2a72893 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/BasalSchedule.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/BasalSchedule.java @@ -1,10 +1,11 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule; import org.joda.time.Duration; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Objects; public class BasalSchedule { private final List entries; @@ -15,7 +16,7 @@ public class BasalSchedule { } else if (!entries.get(0).getStartTime().isEqual(Duration.ZERO)) { throw new IllegalArgumentException("First basal schedule entry should have 0 offset"); } - this.entries = entries; + this.entries = new ArrayList<>(entries); } public double rateAt(Duration offset) { @@ -91,12 +92,23 @@ public class BasalSchedule { '}'; } + @Override public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + BasalSchedule that = (BasalSchedule) o; + return entries.equals(that.entries); + } + + @Override public int hashCode() { + return Objects.hash(entries); + } + public static class BasalScheduleDurationEntry { private final double rate; private final Duration duration; private final Duration startTime; - public BasalScheduleDurationEntry(double rate, Duration startTime, Duration duration) { + BasalScheduleDurationEntry(double rate, Duration startTime, Duration duration) { this.rate = rate; this.duration = duration; this.startTime = startTime; @@ -121,7 +133,7 @@ public class BasalSchedule { private final Duration startTime; private final Duration duration; - public BasalScheduleLookupResult(int index, BasalScheduleEntry basalScheduleEntry, Duration startTime, Duration duration) { + BasalScheduleLookupResult(int index, BasalScheduleEntry basalScheduleEntry, Duration startTime, Duration duration) { this.index = index; this.basalScheduleEntry = basalScheduleEntry; this.startTime = startTime; @@ -132,7 +144,7 @@ public class BasalSchedule { return index; } - public BasalScheduleEntry getBasalScheduleEntry() { + BasalScheduleEntry getBasalScheduleEntry() { return basalScheduleEntry; } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/BasalScheduleEntry.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/BasalScheduleEntry.java similarity index 57% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/BasalScheduleEntry.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/BasalScheduleEntry.java index f8065e0f4b..ac6527339c 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/BasalScheduleEntry.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/BasalScheduleEntry.java @@ -1,8 +1,10 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule; import org.joda.time.Duration; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; +import java.util.Objects; + +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; public class BasalScheduleEntry { private final double rate; @@ -13,9 +15,9 @@ public class BasalScheduleEntry { throw new IllegalArgumentException("Invalid start time"); } else if (rate < 0D) { throw new IllegalArgumentException("Rate should be >= 0"); - } else if (rate > OmnipodConst.MAX_BASAL_RATE) { + } else if (rate > OmnipodConstants.MAX_BASAL_RATE) { throw new IllegalArgumentException("Rate exceeds max basal rate"); - } else if (rate % OmnipodConst.POD_PULSE_SIZE > 0.000001 && rate % OmnipodConst.POD_PULSE_SIZE - OmnipodConst.POD_PULSE_SIZE < -0.000001) { + } else if (rate % OmnipodConstants.POD_PULSE_SIZE > 0.000001 && rate % OmnipodConstants.POD_PULSE_SIZE - OmnipodConstants.POD_PULSE_SIZE < -0.000001) { throw new IllegalArgumentException("Unsupported basal rate precision"); } this.rate = rate; @@ -37,4 +39,16 @@ public class BasalScheduleEntry { ", startTime=" + startTime.getStandardSeconds() + "s" + '}'; } + + @Override public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + BasalScheduleEntry that = (BasalScheduleEntry) o; + return Double.compare(that.rate, rate) == 0 && + Objects.equals(startTime, that.startTime); + } + + @Override public int hashCode() { + return Objects.hash(rate, startTime); + } } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/BasalTableEntry.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/BasalTableEntry.java similarity index 89% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/BasalTableEntry.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/BasalTableEntry.java index 55339865a0..bec2a8ae9d 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/BasalTableEntry.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/BasalTableEntry.java @@ -1,7 +1,7 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.IRawRepresentable; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.IRawRepresentable; public class BasalTableEntry implements IRawRepresentable { diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/BolusDeliverySchedule.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/BolusDeliverySchedule.java similarity index 80% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/BolusDeliverySchedule.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/BolusDeliverySchedule.java index 167f1bcce5..bd2100edd3 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/BolusDeliverySchedule.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/BolusDeliverySchedule.java @@ -1,10 +1,10 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule; import org.joda.time.Duration; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.IRawRepresentable; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.IRawRepresentable; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; public class BolusDeliverySchedule extends DeliverySchedule implements IRawRepresentable { @@ -14,7 +14,7 @@ public class BolusDeliverySchedule extends DeliverySchedule implements IRawRepre public BolusDeliverySchedule(double units, Duration timeBetweenPulses) { if (units <= 0D) { throw new IllegalArgumentException("Units should be > 0"); - } else if (units > OmnipodConst.MAX_BOLUS) { + } else if (units > OmnipodConstants.MAX_BOLUS) { throw new IllegalArgumentException("Units exceeds max bolus"); } this.units = units; @@ -25,7 +25,7 @@ public class BolusDeliverySchedule extends DeliverySchedule implements IRawRepre public byte[] getRawData() { byte[] rawData = new byte[]{1}; // Number of half hour segments - int pulseCount = (int) Math.round(units / OmnipodConst.POD_PULSE_SIZE); + int pulseCount = (int) Math.round(units / OmnipodConstants.POD_PULSE_SIZE); int multiplier = (int) timeBetweenPulses.getStandardSeconds() * 8; int fieldA = pulseCount * multiplier; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/DeliverySchedule.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/DeliverySchedule.java new file mode 100644 index 0000000000..c5cc98ccad --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/DeliverySchedule.java @@ -0,0 +1,10 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule; + +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.IRawRepresentable; + +public abstract class DeliverySchedule implements IRawRepresentable { + + public abstract InsulinScheduleType getType(); + + public abstract int getChecksum(); +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/InsulinScheduleType.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/InsulinScheduleType.java similarity index 80% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/InsulinScheduleType.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/InsulinScheduleType.java index 6c7a364e2d..76872a98e1 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/InsulinScheduleType.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/InsulinScheduleType.java @@ -1,11 +1,11 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule; public enum InsulinScheduleType { BASAL_SCHEDULE(0), TEMP_BASAL_SCHEDULE(1), BOLUS(2); - private byte value; + private final byte value; InsulinScheduleType(int value) { this.value = (byte) value; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/RateEntry.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/RateEntry.java similarity index 84% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/RateEntry.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/RateEntry.java index c9bda11562..e3d5d7cf28 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/RateEntry.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/RateEntry.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule; import org.joda.time.Duration; @@ -6,8 +6,8 @@ import java.util.ArrayList; import java.util.List; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.IRawRepresentable; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.IRawRepresentable; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; public class RateEntry implements IRawRepresentable { @@ -15,7 +15,7 @@ public class RateEntry implements IRawRepresentable { // We use a double for the delay between pulses because the Joda time API lacks precision for our calculations private final double delayBetweenPulsesInSeconds; - public RateEntry(double totalPulses, double delayBetweenPulsesInSeconds) { + private RateEntry(double totalPulses, double delayBetweenPulsesInSeconds) { this.totalPulses = totalPulses; this.delayBetweenPulsesInSeconds = delayBetweenPulsesInSeconds; } @@ -23,13 +23,13 @@ public class RateEntry implements IRawRepresentable { public static List createEntries(double rate, Duration duration) { List entries = new ArrayList<>(); int remainingSegments = (int) Math.round(duration.getStandardSeconds() / 1800.0); - double pulsesPerSegment = (int) Math.round(rate / OmnipodConst.POD_PULSE_SIZE) / 2.0; + double pulsesPerSegment = (int) Math.round(rate / OmnipodConstants.POD_PULSE_SIZE) / 2.0; int maxSegmentsPerEntry = pulsesPerSegment > 0 ? (int) (BasalDeliveryTable.MAX_PULSES_PER_RATE_ENTRY / pulsesPerSegment) : 1; double durationInHours = duration.getStandardSeconds() / 3600.0; - double remainingPulses = rate * durationInHours / OmnipodConst.POD_PULSE_SIZE; - double delayBetweenPulses = 3600 / rate * OmnipodConst.POD_PULSE_SIZE; + double remainingPulses = rate * durationInHours / OmnipodConstants.POD_PULSE_SIZE; + double delayBetweenPulses = 3600 / rate * OmnipodConstants.POD_PULSE_SIZE; while (remainingSegments > 0) { if (rate == 0.0) { diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/TempBasalDeliverySchedule.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/TempBasalDeliverySchedule.java similarity index 91% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/TempBasalDeliverySchedule.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/TempBasalDeliverySchedule.java index a4c320b1d3..8c08b21103 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/schedule/TempBasalDeliverySchedule.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/TempBasalDeliverySchedule.java @@ -1,7 +1,7 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.IRawRepresentable; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.IRawRepresentable; public class TempBasalDeliverySchedule extends DeliverySchedule implements IRawRepresentable { diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/ActionInitializationException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/ActionInitializationException.java similarity index 51% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/ActionInitializationException.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/ActionInitializationException.java index 5682b0c6c7..1de5bf13dc 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/ActionInitializationException.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/ActionInitializationException.java @@ -1,6 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.exception; - -import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception; public class ActionInitializationException extends OmnipodException { public ActionInitializationException(String message) { diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/CommandFailedAfterChangingDeliveryStatusException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/CommandFailedAfterChangingDeliveryStatusException.java new file mode 100644 index 0000000000..225497853d --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/CommandFailedAfterChangingDeliveryStatusException.java @@ -0,0 +1,7 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception; + +public class CommandFailedAfterChangingDeliveryStatusException extends OmnipodException { + public CommandFailedAfterChangingDeliveryStatusException(String message, Throwable cause) { + super(message, cause, false); + } +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/CommandInitializationException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/CommandInitializationException.java similarity index 65% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/CommandInitializationException.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/CommandInitializationException.java index cb0553f292..57bd2c0189 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/CommandInitializationException.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/CommandInitializationException.java @@ -1,6 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.exception; - -import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception; public class CommandInitializationException extends OmnipodException { public CommandInitializationException(String message) { diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/CommunicationException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/CommunicationException.java similarity index 83% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/CommunicationException.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/CommunicationException.java index 8b1215b1aa..e9a7eb3bd0 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/CommunicationException.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/CommunicationException.java @@ -1,6 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.exception; - -import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception; public class CommunicationException extends OmnipodException { private final Type type; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/CrcMismatchException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/CrcMismatchException.java similarity index 76% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/CrcMismatchException.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/CrcMismatchException.java index 3de98e6f49..5dcffa1e2e 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/CrcMismatchException.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/CrcMismatchException.java @@ -1,9 +1,7 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.exception; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception; import java.util.Locale; -import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException; - public class CrcMismatchException extends OmnipodException { private final int expected; private final int actual; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/DeliveryStatusVerificationFailedException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/DeliveryStatusVerificationFailedException.java new file mode 100644 index 0000000000..f6c86561dc --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/DeliveryStatusVerificationFailedException.java @@ -0,0 +1,16 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception; + +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryStatus; + +public class DeliveryStatusVerificationFailedException extends OmnipodException { + private final DeliveryStatus expectedStatus; + + public DeliveryStatusVerificationFailedException(DeliveryStatus expectedStatus, Throwable cause) { + super("Failed to verify delivery status (expected=" + expectedStatus + ")", cause, false); + this.expectedStatus = expectedStatus; + } + + public DeliveryStatus getExpectedStatus() { + return expectedStatus; + } +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/IllegalDeliveryStatusException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalDeliveryStatusException.java similarity index 72% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/IllegalDeliveryStatusException.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalDeliveryStatusException.java index 6d43eae501..a6f8d22714 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/IllegalDeliveryStatusException.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalDeliveryStatusException.java @@ -1,9 +1,8 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.exception; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception; import java.util.Locale; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.DeliveryStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryStatus; public class IllegalDeliveryStatusException extends OmnipodException { private final DeliveryStatus expected; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/IllegalMessageAddressException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalMessageAddressException.java similarity index 75% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/IllegalMessageAddressException.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalMessageAddressException.java index cd8385d442..1e6a036e63 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/IllegalMessageAddressException.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalMessageAddressException.java @@ -1,6 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.exception; - -import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception; public class IllegalMessageAddressException extends OmnipodException { private final int expected; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/IllegalMessageSequenceNumberException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalMessageSequenceNumberException.java similarity index 76% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/IllegalMessageSequenceNumberException.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalMessageSequenceNumberException.java index 4080ef9764..6d9c436145 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/IllegalMessageSequenceNumberException.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalMessageSequenceNumberException.java @@ -1,6 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.exception; - -import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception; public class IllegalMessageSequenceNumberException extends OmnipodException { private final int expected; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/IllegalPacketTypeException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalPacketTypeException.java similarity index 72% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/IllegalPacketTypeException.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalPacketTypeException.java index 9856d3368c..03d6a425e7 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/IllegalPacketTypeException.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalPacketTypeException.java @@ -1,9 +1,8 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.exception; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception; import java.util.Locale; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PacketType; -import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PacketType; public class IllegalPacketTypeException extends OmnipodException { private final PacketType expected; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/IllegalPodProgressException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalPodProgressException.java similarity index 72% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/IllegalPodProgressException.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalPodProgressException.java index e4e575405e..da319d5d83 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/IllegalPodProgressException.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalPodProgressException.java @@ -1,9 +1,8 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.exception; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception; import java.util.Locale; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodProgressStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; public class IllegalPodProgressException extends OmnipodException { private final PodProgressStatus expected; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/IllegalResponseException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalResponseException.java similarity index 74% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/IllegalResponseException.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalResponseException.java index 647309c478..d6226afe99 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/IllegalResponseException.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalResponseException.java @@ -1,9 +1,8 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.exception; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception; import java.util.Locale; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.MessageBlockType; -import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.MessageBlockType; public class IllegalResponseException extends OmnipodException { private final String actualClass; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/IllegalVersionResponseTypeException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalVersionResponseTypeException.java similarity index 63% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/IllegalVersionResponseTypeException.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalVersionResponseTypeException.java index 79c42a948d..4cfbd76ce9 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/IllegalVersionResponseTypeException.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalVersionResponseTypeException.java @@ -1,6 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.exception; - -import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception; public class IllegalVersionResponseTypeException extends OmnipodException { public IllegalVersionResponseTypeException(String expected, String actual) { diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/MessageDecodingException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/MessageDecodingException.java similarity index 63% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/MessageDecodingException.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/MessageDecodingException.java index 5e1c4f3523..05d61b19dd 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/MessageDecodingException.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/MessageDecodingException.java @@ -1,6 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.exception; - -import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception; public class MessageDecodingException extends OmnipodException { public MessageDecodingException(String message) { diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/NonceOutOfSyncException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/NonceOutOfSyncException.java new file mode 100644 index 0000000000..1b128b58fc --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/NonceOutOfSyncException.java @@ -0,0 +1,7 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception; + +public class NonceOutOfSyncException extends OmnipodException { + public NonceOutOfSyncException() { + super("Nonce out of sync", true); + } +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/NonceResyncException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/NonceResyncException.java new file mode 100644 index 0000000000..4e534c20b3 --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/NonceResyncException.java @@ -0,0 +1,7 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception; + +public class NonceResyncException extends OmnipodException { + public NonceResyncException() { + super("Nonce resync failed", true); + } +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/NotEnoughDataException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/NotEnoughDataException.java similarity index 71% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/NotEnoughDataException.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/NotEnoughDataException.java index 728fa4d734..c54ed82384 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/NotEnoughDataException.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/NotEnoughDataException.java @@ -1,7 +1,6 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.exception; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException; public class NotEnoughDataException extends OmnipodException { private final byte[] data; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/exception/OmnipodException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/OmnipodException.java similarity index 67% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/exception/OmnipodException.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/OmnipodException.java index 22cc9cd020..d4eb40ae94 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/exception/OmnipodException.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/OmnipodException.java @@ -1,14 +1,14 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.exception; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception; public abstract class OmnipodException extends RuntimeException { private boolean certainFailure; - public OmnipodException(String message, boolean certainFailure) { + OmnipodException(String message, boolean certainFailure) { super(message); this.certainFailure = certainFailure; } - public OmnipodException(String message, Throwable cause, boolean certainFailure) { + OmnipodException(String message, Throwable cause, boolean certainFailure) { super(message, cause); this.certainFailure = certainFailure; } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/PodFaultException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/PodFaultException.java similarity index 58% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/PodFaultException.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/PodFaultException.java index 7f90a3af36..884e7481eb 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/PodFaultException.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/PodFaultException.java @@ -1,7 +1,6 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.exception; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoFaultEvent; -import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoFaultEvent; public class PodFaultException extends OmnipodException { private final PodInfoFaultEvent faultEvent; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/PodReturnedErrorResponseException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/PodReturnedErrorResponseException.java similarity index 62% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/PodReturnedErrorResponseException.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/PodReturnedErrorResponseException.java index d552151142..bc2bd92af9 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/exception/PodReturnedErrorResponseException.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/PodReturnedErrorResponseException.java @@ -1,7 +1,6 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm.exception; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.ErrorResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.ErrorResponse; public class PodReturnedErrorResponseException extends OmnipodException { private final ErrorResponse errorResponse; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodManager.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/OmnipodManager.java similarity index 56% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodManager.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/OmnipodManager.java index a6576583ae..9da707a26b 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodManager.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/OmnipodManager.java @@ -1,10 +1,11 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.manager; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.joda.time.Duration; import java.util.EnumSet; +import java.util.List; import java.util.TimeZone; import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; @@ -12,40 +13,43 @@ import java.util.function.Supplier; import info.nightscout.androidaps.logging.AAPSLogger; import info.nightscout.androidaps.logging.LTag; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.AcknowledgeAlertsAction; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.AssignAddressAction; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.BolusAction; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.CancelDeliveryAction; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.DeactivatePodAction; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.GetPodInfoAction; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.GetStatusAction; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.InsertCannulaAction; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.PrimeAction; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.SetBasalScheduleAction; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.SetTempBasalAction; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.SetupPodAction; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.service.InsertCannulaService; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.service.PrimeService; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.CommunicationException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalDeliveryStatusException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalPacketTypeException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalPodProgressException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.NonceOutOfSyncException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.PodFaultException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.CancelDeliveryCommand; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoRecentPulseLog; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.BeepType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.DeliveryStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.DeliveryType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PacketType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodProgressStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BasalSchedule; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; -import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.AcknowledgeAlertsAction; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.AssignAddressAction; +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.DeactivatePodAction; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.GetPodInfoAction; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.GetStatusAction; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.InsertCannulaAction; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.PrimeAction; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.SetBasalScheduleAction; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.SetTempBasalAction; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.SetupPodAction; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.service.PrimeService; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.CancelDeliveryCommand; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoRecentPulseLog; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertConfiguration; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.BeepType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PacketType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalSchedule; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.CommandFailedAfterChangingDeliveryStatusException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.CommunicationException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.DeliveryStatusVerificationFailedException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalDeliveryStatusException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPacketTypeException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.NonceOutOfSyncException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.OmnipodException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.PodFaultException; +import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; import info.nightscout.androidaps.utils.sharedPreferences.SP; import io.reactivex.Completable; import io.reactivex.Flowable; @@ -57,7 +61,7 @@ import io.reactivex.subjects.SingleSubject; public class OmnipodManager { private static final int ACTION_VERIFICATION_TRIES = 3; - private final OmnipodCommunicationManager communicationService; + private final OmnipodRileyLinkCommunicationManager communicationService; private PodStateManager podStateManager; private ActiveBolusData activeBolusData; @@ -69,7 +73,7 @@ public class OmnipodManager { public OmnipodManager(AAPSLogger aapsLogger, SP sp, - OmnipodCommunicationManager communicationService, + OmnipodRileyLinkCommunicationManager communicationService, PodStateManager podStateManager) { if (communicationService == null) { throw new IllegalArgumentException("Communication service cannot be null"); @@ -122,14 +126,15 @@ public class OmnipodManager { logCommandExecutionFinished("pairAndPrime"); } - long delayInSeconds = calculateBolusDuration(OmnipodConst.POD_PRIME_BOLUS_UNITS, OmnipodConst.POD_PRIMING_DELIVERY_RATE).getStandardSeconds(); + long delayInSeconds = calculateBolusDuration(OmnipodConstants.POD_PRIME_BOLUS_UNITS, OmnipodConstants.POD_PRIMING_DELIVERY_RATE).getStandardSeconds(); return Single.timer(delayInSeconds, TimeUnit.SECONDS) // .map(o -> verifySetupAction(PodProgressStatus.PRIMING_COMPLETED)) // .observeOn(Schedulers.io()); } - public synchronized Single insertCannula(BasalSchedule basalSchedule) { + public synchronized Single insertCannula( + BasalSchedule basalSchedule, Duration expirationReminderTimeBeforeShutdown, Integer lowReservoirAlertUnits) { if (!podStateManager.isPodInitialized() || podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.PRIMING_COMPLETED)) { throw new IllegalPodProgressException(PodProgressStatus.PRIMING_COMPLETED, !podStateManager.isPodInitialized() ? null : podStateManager.getPodProgressStatus()); } @@ -144,12 +149,12 @@ public class OmnipodManager { logStartingCommandExecution("insertCannula [basalSchedule=" + basalSchedule + "]"); try { - communicationService.executeAction(new InsertCannulaAction(new InsertCannulaService(), podStateManager, basalSchedule)); + communicationService.executeAction(new InsertCannulaAction(podStateManager, basalSchedule, expirationReminderTimeBeforeShutdown, lowReservoirAlertUnits)); } finally { logCommandExecutionFinished("insertCannula"); } - long delayInSeconds = calculateBolusDuration(OmnipodConst.POD_CANNULA_INSERTION_BOLUS_UNITS, OmnipodConst.POD_CANNULA_INSERTION_DELIVERY_RATE).getStandardSeconds(); + long delayInSeconds = calculateBolusDuration(OmnipodConstants.POD_CANNULA_INSERTION_BOLUS_UNITS, OmnipodConstants.POD_CANNULA_INSERTION_DELIVERY_RATE).getStandardSeconds(); return Single.timer(delayInSeconds, TimeUnit.SECONDS) // .map(o -> verifySetupAction(PodProgressStatus.ABOVE_FIFTY_UNITS)) // @@ -182,6 +187,18 @@ public class OmnipodManager { } } + public synchronized StatusResponse configureAlerts(List alertConfigurations) { + assertReadyForDelivery(); + logStartingCommandExecution("configureAlerts"); + try { + StatusResponse statusResponse = executeAndVerify(() -> communicationService.executeAction(new ConfigureAlertsAction(podStateManager, alertConfigurations))); + ConfigureAlertsAction.updateConfiguredAlerts(podStateManager, alertConfigurations); + return statusResponse; + } finally { + logCommandExecutionFinished("configureAlerts"); + } + } + public synchronized StatusResponse acknowledgeAlerts() { assertReadyForDelivery(); @@ -196,27 +213,40 @@ public class OmnipodManager { // CAUTION: cancels all delivery // CAUTION: suspends and then resumes delivery. An OmnipodException[certainFailure=false] indicates that the pod is or might be suspended - public synchronized StatusResponse setBasalSchedule(BasalSchedule schedule, boolean acknowledgementBeep) { + public synchronized void setBasalSchedule(BasalSchedule schedule, boolean acknowledgementBeep) { assertReadyForDelivery(); logStartingCommandExecution("setBasalSchedule [basalSchedule=" + schedule + ", acknowledgementBeep=" + acknowledgementBeep + "]"); try { - cancelDelivery(EnumSet.allOf(DeliveryType.class), acknowledgementBeep); - } catch (Exception ex) { - logCommandExecutionFinished("setBasalSchedule"); - throw ex; - } + boolean wasSuspended = podStateManager.isSuspended(); + if (!wasSuspended) { + suspendDelivery(acknowledgementBeep); + } + + // Store the new Basal schedule after successfully suspending delivery, so that if setting the Basal schedule fails, + // And we later try to resume delivery, the new schedule is used + podStateManager.setBasalSchedule(schedule); - try { try { - return executeAndVerify(() -> communicationService.executeAction(new SetBasalScheduleAction(podStateManager, schedule, + executeAndVerify(() -> communicationService.executeAction(new SetBasalScheduleAction(podStateManager, schedule, false, podStateManager.getScheduleOffset(), acknowledgementBeep))); } catch (OmnipodException ex) { - // Treat all exceptions as uncertain failures, because all delivery has been suspended here. - // Setting this to an uncertain failure will enable for the user to get an appropriate warning - ex.setCertainFailure(false); - throw ex; + if (ex.isCertainFailure()) { + if (!wasSuspended) { + throw new CommandFailedAfterChangingDeliveryStatusException("Suspending delivery succeeded but setting the new basal schedule did not", ex); + } + throw ex; + } + + // verifyDeliveryStatus will throw an exception if verification fails + if (!verifyDeliveryStatus(DeliveryStatus.NORMAL, ex)) { + if (!wasSuspended) { + throw new CommandFailedAfterChangingDeliveryStatusException("Suspending delivery succeeded but setting the new basal schedule did not", ex); + } + ex.setCertainFailure(true); + throw ex; + } } } finally { logCommandExecutionFinished("setBasalSchedule"); @@ -224,28 +254,67 @@ public class OmnipodManager { } // CAUTION: cancels temp basal and then sets new temp basal. An OmnipodException[certainFailure=false] indicates that the pod might have cancelled the previous temp basal, but did not set a new temp basal - public synchronized StatusResponse setTemporaryBasal(double rate, Duration duration, boolean acknowledgementBeep, boolean completionBeep) { + public synchronized void setTemporaryBasal(double rate, Duration duration, boolean acknowledgementBeep, boolean completionBeep) { assertReadyForDelivery(); logStartingCommandExecution("setTemporaryBasal [rate=" + rate + ", duration=" + duration + ", acknowledgementBeep=" + acknowledgementBeep + ", completionBeep=" + completionBeep + "]"); - try { - cancelDelivery(EnumSet.of(DeliveryType.TEMP_BASAL), acknowledgementBeep); - } catch (Exception ex) { - logCommandExecutionFinished("setTemporaryBasal"); - throw ex; - } + boolean cancelCurrentTbr = podStateManager.isTempBasalRunning(); try { - StatusResponse statusResponse = executeAndVerify(() -> communicationService.executeAction(new SetTempBasalAction( - podStateManager, rate, duration, - acknowledgementBeep, completionBeep))); - return statusResponse; - } catch (OmnipodException ex) { - // Treat all exceptions as uncertain failures, because all delivery has been suspended here. - // Setting this to an uncertain failure will enable for the user to get an appropriate warning - ex.setCertainFailure(false); - throw ex; + if (cancelCurrentTbr) { + try { + cancelDelivery(EnumSet.of(DeliveryType.TEMP_BASAL), acknowledgementBeep); + } catch (OmnipodException ex) { + if (ex.isCertainFailure()) { + throw ex; + } + + // verifyDeliveryStatus will throw an exception if verification fails + if (!verifyDeliveryStatus(DeliveryStatus.NORMAL, ex)) { + ex.setCertainFailure(true); + throw ex; + } + } + } + + try { + 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()) { + if (cancelCurrentTbr) { + throw new CommandFailedAfterChangingDeliveryStatusException("Failed to set new TBR while cancelling old TBR succeeded", ex); + } + throw ex; + } + + // verifyDeliveryStatus will throw an exception if verification fails + try { + if (verifyDeliveryStatus(DeliveryStatus.TEMP_BASAL_RUNNING, ex)) { + podStateManager.setTempBasal(DateTime.now().minus(OmnipodConstants.AVERAGE_TEMP_BASAL_COMMAND_COMMUNICATION_DURATION), rate, duration, true); + } else { + if (cancelCurrentTbr) { + throw new CommandFailedAfterChangingDeliveryStatusException("Failed to set new TBR while cancelling old TBR succeeded", ex); + } + + ex.setCertainFailure(true); + throw ex; + } + } catch (CommandFailedAfterChangingDeliveryStatusException ex2) { + // Don't set temp basal in Pod State for this Exception + throw ex2; + } catch (OmnipodException ex2) { + if (!ex2.isCertainFailure()) { + // We're not sure that setting the new TBR failed, so we assume that it succeeded + // If it didn't, PodStateManager.updateFromResponse() will fix the state + // upon receiving the next StatusResponse + podStateManager.setTempBasal(DateTime.now().minus(OmnipodConstants.AVERAGE_TEMP_BASAL_COMMAND_COMMUNICATION_DURATION), rate, duration, false); + } + throw ex2; + } + } } finally { logCommandExecutionFinished("setTemporaryBasal"); } @@ -263,7 +332,7 @@ public class OmnipodManager { try { return executeAndVerify(() -> { StatusResponse statusResponse = communicationService.executeAction(new CancelDeliveryAction(podStateManager, deliveryTypes, acknowledgementBeep)); - aapsLogger.info(LTag.PUMPBTCOMM, "Status response after cancel delivery[types={}]: {}", deliveryTypes.toString(), statusResponse.toString()); + aapsLogger.info(LTag.PUMPCOMM, "Status response after cancel delivery[types={}]: {}", deliveryTypes.toString(), statusResponse.toString()); return statusResponse; }); } finally { @@ -293,20 +362,20 @@ public class OmnipodManager { } // Catch uncertain exceptions as we still want to report bolus progress indication - aapsLogger.error(LTag.PUMPBTCOMM, "Caught exception[certainFailure=false] in bolus", ex); + aapsLogger.error(LTag.PUMPCOMM, "Caught exception[certainFailure=false] in bolus", ex); commandDeliveryStatus = CommandDeliveryStatus.UNCERTAIN_FAILURE; - } finally { - logCommandExecutionFinished("bolus"); } - DateTime startDate = DateTime.now().minus(OmnipodConst.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION); - podStateManager.setLastBolus(startDate, units); + DateTime estimatedBolusStartDate = DateTime.now().minus(OmnipodConstants.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION); + Duration estimatedBolusDuration = calculateBolusDuration(units, OmnipodConstants.POD_BOLUS_DELIVERY_RATE); + Duration estimatedRemainingBolusDuration = estimatedBolusDuration.minus(OmnipodConstants.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION); + + podStateManager.setLastBolus(estimatedBolusStartDate, units, estimatedBolusDuration, commandDeliveryStatus == CommandDeliveryStatus.SUCCESS); CompositeDisposable disposables = new CompositeDisposable(); - Duration bolusDuration = calculateBolusDuration(units, OmnipodConst.POD_BOLUS_DELIVERY_RATE); - Duration estimatedRemainingBolusDuration = bolusDuration.minus(OmnipodConst.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION); if (progressIndicationConsumer != null) { + int numberOfProgressReports = Math.max(20, Math.min(100, (int) Math.ceil(units) * 10)); long progressReportInterval = estimatedRemainingBolusDuration.getMillis() / numberOfProgressReports; @@ -322,7 +391,7 @@ public class OmnipodManager { SingleSubject bolusCompletionSubject = SingleSubject.create(); synchronized (bolusDataMutex) { - activeBolusData = new ActiveBolusData(units, startDate, bolusCompletionSubject, disposables); + activeBolusData = new ActiveBolusData(units, estimatedBolusStartDate, commandDeliveryStatus, bolusCompletionSubject, disposables); } // Return successful command execution AFTER storing activeBolusData @@ -335,7 +404,7 @@ public class OmnipodManager { .observeOn(Schedulers.io()) // .doOnComplete(() -> { synchronized (bolusDataMutex) { - double unitsNotDelivered = 0.0d; + double bolusNotDelivered = 0.0d; for (int i = 0; i < ACTION_VERIFICATION_TRIES; i++) { try { @@ -347,24 +416,26 @@ public class OmnipodManager { break; } } catch (PodFaultException ex) { - // Substract units not delivered in case of a Pod failure - unitsNotDelivered = ex.getFaultEvent().getInsulinNotDelivered(); + // Subtract units not delivered in case of a Pod failure + bolusNotDelivered = ex.getFaultEvent().getBolusNotDelivered(); - aapsLogger.debug(LTag.PUMPBTCOMM, "Caught PodFaultException in bolus completion verification", ex); + aapsLogger.debug(LTag.PUMPCOMM, "Caught PodFaultException in bolus completion verification", ex); break; } catch (Exception ex) { - aapsLogger.debug(LTag.PUMPBTCOMM, "Ignoring exception in bolus completion verification", ex); + aapsLogger.debug(LTag.PUMPCOMM, "Ignoring exception in bolus completion verification", ex); } } if (hasActiveBolus()) { - activeBolusData.bolusCompletionSubject.onSuccess(new BolusDeliveryResult(units - unitsNotDelivered)); + activeBolusData.bolusCompletionSubject.onSuccess(new BolusDeliveryResult(units - bolusNotDelivered)); activeBolusData = null; } } }) .subscribe()); + logCommandExecutionFinished("bolus"); + return new BolusCommandResult(commandDeliveryStatus, bolusCompletionSubject); } @@ -380,9 +451,9 @@ public class OmnipodManager { try { StatusResponse statusResponse = cancelDelivery(EnumSet.of(DeliveryType.BOLUS), acknowledgementBeep); - discardActiveBolusData(statusResponse.getInsulinNotDelivered()); + discardActiveBolusData(statusResponse.getBolusNotDelivered()); } catch (PodFaultException ex) { - discardActiveBolusData(ex.getFaultEvent().getInsulinNotDelivered()); + discardActiveBolusData(ex.getFaultEvent().getBolusNotDelivered()); throw ex; } finally { logCommandExecutionFinished("cancelBolus"); @@ -390,10 +461,10 @@ public class OmnipodManager { } } - private void discardActiveBolusData(double unitsNotDelivered) { + private void discardActiveBolusData(double bolusNotDelivered) { synchronized (bolusDataMutex) { - double unitsDelivered = activeBolusData.getUnits() - unitsNotDelivered; - podStateManager.setLastBolus(activeBolusData.getStartDate(), unitsDelivered); + double unitsDelivered = activeBolusData.getUnits() - bolusNotDelivered; + podStateManager.setLastBolus(activeBolusData.getStartDate(), unitsDelivered, new Duration(activeBolusData.getStartDate(), DateTime.now()), activeBolusData.getCommandDeliveryStatus() == CommandDeliveryStatus.SUCCESS); activeBolusData.getDisposables().dispose(); activeBolusData.getBolusCompletionSubject().onSuccess(new BolusDeliveryResult(unitsDelivered)); activeBolusData = null; @@ -401,19 +472,24 @@ public class OmnipodManager { } public synchronized void suspendDelivery(boolean acknowledgementBeep) { - cancelDelivery(EnumSet.allOf(DeliveryType.class), acknowledgementBeep); - } - - // Same as setting basal schedule, but without suspending delivery first - public synchronized StatusResponse resumeDelivery(boolean acknowledgementBeep) { assertReadyForDelivery(); - logStartingCommandExecution("resumeDelivery"); + + logStartingCommandExecution("suspendDelivery"); try { - return executeAndVerify(() -> communicationService.executeAction(new SetBasalScheduleAction(podStateManager, podStateManager.getBasalSchedule(), - false, podStateManager.getScheduleOffset(), acknowledgementBeep))); + cancelDelivery(EnumSet.allOf(DeliveryType.class), acknowledgementBeep); + } catch (OmnipodException ex) { + if (ex.isCertainFailure()) { + throw ex; + } + + // verifyDeliveryStatus will throw an exception if verification fails + if (!verifyDeliveryStatus(DeliveryStatus.SUSPENDED, ex)) { + ex.setCertainFailure(true); + throw ex; + } } finally { - logCommandExecutionFinished("resumeDelivery"); + logCommandExecutionFinished("suspendDelivery"); } } @@ -425,26 +501,18 @@ public class OmnipodManager { logStartingCommandExecution("setTime [acknowledgementBeeps=" + acknowledgementBeeps + "]"); try { - cancelDelivery(EnumSet.allOf(DeliveryType.class), acknowledgementBeeps); - } catch (Exception ex) { - logCommandExecutionFinished("setTime"); - throw ex; - } + DateTimeZone oldTimeZone = podStateManager.getTimeZone(); - DateTimeZone oldTimeZone = podStateManager.getTimeZone(); + try { + // Joda seems to cache the default time zone, so we use the JVM's + DateTimeZone.setDefault(DateTimeZone.forTimeZone(TimeZone.getDefault())); + podStateManager.setTimeZone(DateTimeZone.getDefault()); - try { - // Joda seems to cache the default time zone, so we use the JVM's - DateTimeZone.setDefault(DateTimeZone.forTimeZone(TimeZone.getDefault())); - podStateManager.setTimeZone(DateTimeZone.getDefault()); - - setBasalSchedule(podStateManager.getBasalSchedule(), acknowledgementBeeps); - } catch (OmnipodException ex) { - // Treat all exceptions as uncertain failures, because all delivery has been suspended here. - // Setting this to an uncertain failure will enable for the user to get an appropriate warning - podStateManager.setTimeZone(oldTimeZone); - ex.setCertainFailure(false); - throw ex; + setBasalSchedule(podStateManager.getBasalSchedule(), acknowledgementBeeps); + } catch (OmnipodException ex) { + podStateManager.setTimeZone(oldTimeZone); + throw ex; + } } finally { logCommandExecutionFinished("setTime"); } @@ -458,28 +526,27 @@ public class OmnipodManager { logStartingCommandExecution("deactivatePod"); // Try to get pulse log for diagnostics - // FIXME replace by storing to file try { PodInfoResponse podInfoResponse = communicationService.executeAction(new GetPodInfoAction(podStateManager, PodInfoType.RECENT_PULSE_LOG)); - PodInfoRecentPulseLog pulseLogInfo = podInfoResponse.getPodInfo(); - aapsLogger.info(LTag.PUMPBTCOMM, "Retrieved pulse log from the pod: {}", pulseLogInfo.toString()); + PodInfoRecentPulseLog pulseLogInfo = (PodInfoRecentPulseLog) podInfoResponse.getPodInfo(); + aapsLogger.info(LTag.PUMPCOMM, "Retrieved pulse log from the pod: {}", pulseLogInfo.toString()); } catch (Exception ex) { - aapsLogger.warn(LTag.PUMPBTCOMM, "Failed to retrieve pulse log from the pod", ex); + aapsLogger.warn(LTag.PUMPCOMM, "Failed to retrieve pulse log from the pod", ex); } try { // Always send acknowledgement beeps here. Matches the PDM's behavior communicationService.executeAction(new DeactivatePodAction(podStateManager, true)); } catch (PodFaultException ex) { - aapsLogger.info(LTag.PUMPBTCOMM, "Ignoring PodFaultException in deactivatePod", ex); + aapsLogger.info(LTag.PUMPCOMM, "Ignoring PodFaultException in deactivatePod", ex); } finally { logCommandExecutionFinished("deactivatePod"); } - podStateManager.removeState(); + podStateManager.discardState(); } - public OmnipodCommunicationManager getCommunicationService() { + public OmnipodRileyLinkCommunicationManager getCommunicationService() { return communicationService; } @@ -487,10 +554,6 @@ public class OmnipodManager { return podStateManager.getTime(); } - public boolean isPodRunning() { - return podStateManager.isPodRunning(); - } - public boolean hasActiveBolus() { synchronized (bolusDataMutex) { return activeBolusData != null; @@ -501,26 +564,29 @@ public class OmnipodManager { return bolusCommandExecutionSubject; } + private boolean isPodRunning() { + return podStateManager.isPodRunning(); + } + // Only works for commands with nonce resyncable message blocks - // FIXME method is too big, needs refactoring private StatusResponse executeAndVerify(Supplier supplier) { + logStartingCommandExecution("verifyCommand"); try { return supplier.get(); } catch (Exception originalException) { if (isCertainFailure(originalException)) { throw originalException; } else { - aapsLogger.warn(LTag.PUMPBTCOMM, "Caught exception in executeAndVerify. Verifying command by using cancel none command to verify nonce", originalException); + aapsLogger.warn(LTag.PUMPCOMM, "Caught exception in executeAndVerify. Verifying command by using cancel none command to verify nonce", originalException); try { - logStartingCommandExecution("verifyCommand"); StatusResponse statusResponse = communicationService.sendCommand(StatusResponse.class, podStateManager, new CancelDeliveryCommand(podStateManager.getCurrentNonce(), BeepType.NO_BEEP, DeliveryType.NONE), false); - aapsLogger.info(LTag.PUMPBTCOMM, "Command status resolved to SUCCESS. Status response after cancelDelivery[types=DeliveryType.NONE]: {}", statusResponse); + aapsLogger.info(LTag.PUMPCOMM, "Command status resolved to SUCCESS. Status response after cancelDelivery[types=DeliveryType.NONE]: {}", statusResponse); return statusResponse; } catch (NonceOutOfSyncException verificationException) { - aapsLogger.error(LTag.PUMPBTCOMM, "Command resolved to FAILURE (CERTAIN_FAILURE)", verificationException); + aapsLogger.error(LTag.PUMPCOMM, "Command resolved to FAILURE (CERTAIN_FAILURE)", verificationException); if (originalException instanceof OmnipodException) { ((OmnipodException) originalException).setCertainFailure(true); @@ -531,12 +597,12 @@ public class OmnipodManager { throw newException; } } catch (Exception verificationException) { - aapsLogger.error(LTag.PUMPBTCOMM, "Command unresolved (UNCERTAIN_FAILURE)", verificationException); + aapsLogger.error(LTag.PUMPCOMM, "Command unresolved (UNCERTAIN_FAILURE)", verificationException); throw originalException; - } finally { - logCommandExecutionFinished("verifyCommand"); } } + } finally { + logCommandExecutionFinished("verifyCommand"); } } @@ -568,12 +634,34 @@ public class OmnipodManager { return result; } + /** + * @param expectedStatus expected delivery status + * @param verificationCause the Exception causing us to verify the delivery status + * @return true if the Pod's status matches the expected status, otherwise false + * @throws DeliveryStatusVerificationFailedException in case reading the Pod status fails + */ + private boolean verifyDeliveryStatus(DeliveryStatus expectedStatus, Throwable verificationCause) { + aapsLogger.debug(LTag.PUMPCOMM, "Attempting to verify delivery status (expected={})", expectedStatus); + for (int i = 0; 3 > i; i++) { + try { + StatusResponse podStatus = getPodStatus(); + aapsLogger.debug(LTag.PUMPCOMM, "Resolved delivery status (expected={}, actual={})", expectedStatus, podStatus.getDeliveryStatus()); + return podStatus.getDeliveryStatus().equals(expectedStatus); + } catch (Exception ex) { + aapsLogger.debug(LTag.PUMPCOMM, "Ignoring exception thrown in getPodStatus() during attempt to verify delivery status: {}: {}", + ex.getClass().getSimpleName(), ex.getMessage()); + } + } + aapsLogger.warn(LTag.PUMPCOMM, "Failed to verify delivery status"); + throw new DeliveryStatusVerificationFailedException(expectedStatus, verificationCause); + } + private void logStartingCommandExecution(String action) { - aapsLogger.debug(LTag.PUMPBTCOMM, "Starting command execution for action: " + action); + aapsLogger.debug(LTag.PUMPCOMM, "Starting command execution for action: " + action); } private void logCommandExecutionFinished(String action) { - aapsLogger.debug(LTag.PUMPBTCOMM, "Command execution finished for action: " + action); + aapsLogger.debug(LTag.PUMPCOMM, "Command execution finished for action: " + action); } private static Duration calculateBolusDuration(double units, double deliveryRate) { @@ -583,7 +671,7 @@ public class OmnipodManager { } public static Duration calculateBolusDuration(double units) { - return calculateBolusDuration(units, OmnipodConst.POD_BOLUS_DELIVERY_RATE); + return calculateBolusDuration(units, OmnipodConstants.POD_BOLUS_DELIVERY_RATE); } public static boolean isCertainFailure(Exception ex) { @@ -594,7 +682,7 @@ public class OmnipodManager { private final CommandDeliveryStatus commandDeliveryStatus; private final SingleSubject deliveryResultSubject; - public BolusCommandResult(CommandDeliveryStatus commandDeliveryStatus, SingleSubject deliveryResultSubject) { + BolusCommandResult(CommandDeliveryStatus commandDeliveryStatus, SingleSubject deliveryResultSubject) { this.commandDeliveryStatus = commandDeliveryStatus; this.deliveryResultSubject = deliveryResultSubject; } @@ -611,7 +699,7 @@ public class OmnipodManager { public static class BolusDeliveryResult { private final double unitsDelivered; - public BolusDeliveryResult(double unitsDelivered) { + BolusDeliveryResult(double unitsDelivered) { this.unitsDelivered = unitsDelivered; } @@ -628,40 +716,46 @@ public class OmnipodManager { private static class ActiveBolusData { private final double units; - private volatile DateTime startDate; - private volatile SingleSubject bolusCompletionSubject; - private volatile CompositeDisposable disposables; + private final DateTime startDate; + private final CommandDeliveryStatus commandDeliveryStatus; + private final SingleSubject bolusCompletionSubject; + private final CompositeDisposable disposables; - private ActiveBolusData(double units, DateTime startDate, SingleSubject bolusCompletionSubject, CompositeDisposable disposables) { + private ActiveBolusData(double units, DateTime startDate, CommandDeliveryStatus commandDeliveryStatus, SingleSubject bolusCompletionSubject, CompositeDisposable disposables) { this.units = units; this.startDate = startDate; + this.commandDeliveryStatus = commandDeliveryStatus; this.bolusCompletionSubject = bolusCompletionSubject; this.disposables = disposables; } - public double getUnits() { + double getUnits() { return units; } - public DateTime getStartDate() { + DateTime getStartDate() { return startDate; } - public CompositeDisposable getDisposables() { + CommandDeliveryStatus getCommandDeliveryStatus() { + return commandDeliveryStatus; + } + + CompositeDisposable getDisposables() { return disposables; } - public SingleSubject getBolusCompletionSubject() { + SingleSubject getBolusCompletionSubject() { return bolusCompletionSubject; } - public double estimateUnitsDelivered() { + double estimateUnitsDelivered() { long elapsedMillis = new Duration(startDate, DateTime.now()).getMillis(); - long totalDurationMillis = (long) (units / OmnipodConst.POD_BOLUS_DELIVERY_RATE * 1000); + long totalDurationMillis = (long) (units / OmnipodConstants.POD_BOLUS_DELIVERY_RATE * 1000); double factor = (double) elapsedMillis / totalDurationMillis; double estimatedUnits = Math.min(1D, factor) * units; - int roundingDivisor = (int) (1 / OmnipodConst.POD_PULSE_SIZE); + int roundingDivisor = (int) (1 / OmnipodConstants.POD_PULSE_SIZE); return (double) Math.round(estimatedUnits * roundingDivisor) / roundingDivisor; } } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateManager.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/PodStateManager.java similarity index 66% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateManager.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/PodStateManager.java index 4eafecaa0c..4aed1057f6 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/state/PodStateManager.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/PodStateManager.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs.state; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.manager; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -15,37 +15,38 @@ import org.joda.time.format.ISODateTimeFormat; import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.function.Supplier; import info.nightscout.androidaps.logging.AAPSLogger; import info.nightscout.androidaps.logging.LTag; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoFaultEvent; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSet; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSlot; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.DeliveryStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.FirmwareVersion; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodProgressStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BasalSchedule; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmniCRC; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusUpdatableResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoFaultEvent; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertSet; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertSlot; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.FirmwareVersion; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodCrc; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalSchedule; +// TODO add nullchecks on some setters public abstract class PodStateManager { private final AAPSLogger aapsLogger; private final Gson gsonInstance; private PodState podState; - public PodStateManager(AAPSLogger aapsLogger) { + protected PodStateManager(AAPSLogger aapsLogger) { this.aapsLogger = aapsLogger; this.gsonInstance = createGson(); } - public final void removeState() { + public final void discardState() { this.podState = null; storePodState(); - notifyPodStateChanged(); } public final void initState(int address) { @@ -54,11 +55,10 @@ public abstract class PodStateManager { } podState = new PodState(address); storePodState(); - notifyPodStateChanged(); } /** - * @return true if we have a Pod state (which at least contains an ddress), indicating it is legal to call getters on PodStateManager + * @return true if we have a Pod state (which at least contains an address), indicating it is legal to call getters on PodStateManager */ public final boolean hasPodState() { return podState != null; @@ -89,6 +89,13 @@ public abstract class PodStateManager { return isPodInitialized() && getPodProgressStatus().isRunning(); } + /** + * @return true if the Pod is initialized and a Fault Event has occurred + */ + public final boolean isPodFaulted() { + return isPodInitialized() && podState.getPodProgressStatus().equals(PodProgressStatus.FAULT_EVENT_OCCURRED); + } + /** * @return true if we have a Pod state and the Pod is dead, meaning it is either in a fault state or activation time has been exceeded or it is deactivated */ @@ -97,9 +104,6 @@ public abstract class PodStateManager { } public final void setInitializationParameters(int lot, int tid, FirmwareVersion piVersion, FirmwareVersion pmVersion, DateTimeZone timeZone, PodProgressStatus podProgressStatus) { - if (!hasPodState()) { - throw new IllegalStateException("Cannot set pairing parameters: podState is null"); - } if (isPodInitialized() && getPodProgressStatus().isAfter(PodProgressStatus.REMINDER_INITIALIZED)) { throw new IllegalStateException("Cannot set pairing parameters: pairing parameters have already been set"); } @@ -136,39 +140,47 @@ public abstract class PodStateManager { return getSafe(() -> podState.getMessageNumber()); } + /** + * Does not automatically store pod state in order to decrease I/O load + */ public final void setMessageNumber(int messageNumber) { - setAndStore(() -> podState.setMessageNumber(messageNumber)); + setSafe(() -> podState.setMessageNumber(messageNumber)); } public final int getPacketNumber() { return getSafe(() -> podState.getPacketNumber()); } - public final void setPacketNumber(int packetNumber) { - setAndStore(() -> podState.setPacketNumber(packetNumber)); - } - + /** + * Does not automatically store pod state in order to decrease I/O load + */ public final void increaseMessageNumber() { - setAndStore(() -> podState.setMessageNumber((podState.getMessageNumber() + 1) & 0b1111), false); + setSafe(() -> podState.setMessageNumber((podState.getMessageNumber() + 1) & 0b1111)); } + /** + * Does not automatically store pod state in order to decrease I/O load + */ public final void increasePacketNumber() { - setAndStore(() -> podState.setPacketNumber((podState.getPacketNumber() + 1) & 0b11111), false); + setSafe(() -> podState.setPacketNumber((podState.getPacketNumber() + 1) & 0b11111)); } + /** + * Does not automatically store pod state in order to decrease I/O load + */ public final synchronized void resyncNonce(int syncWord, int sentNonce, int sequenceNumber) { if (!isPodInitialized()) { throw new IllegalStateException("Cannot resync nonce: Pod is not paired yet"); } int sum = (sentNonce & 0xFFFF) - + OmniCRC.crc16lookup[sequenceNumber] + + OmnipodCrc.crc16lookup[sequenceNumber] + (podState.getLot() & 0xFFFF) + (podState.getTid() & 0xFFFF); int seed = ((sum & 0xFFFF) ^ syncWord); NonceState nonceState = new NonceState(podState.getLot(), podState.getTid(), (byte) (seed & 0xFF)); - setAndStore(() -> podState.setNonceState(nonceState), false); + setSafe(() -> podState.setNonceState(nonceState)); } public final synchronized int getCurrentNonce() { @@ -178,33 +190,47 @@ public abstract class PodStateManager { return podState.getNonceState().getCurrentNonce(); } + /** + * Does not automatically store pod state in order to decrease I/O load + */ public final synchronized void advanceToNextNonce() { if (!isPodInitialized()) { throw new IllegalStateException("Cannot advance to next nonce: Pod is not paired yet"); } - setAndStore(() -> podState.getNonceState().advanceToNextNonce(), false); + setSafe(() -> podState.getNonceState().advanceToNextNonce()); } public final DateTime getLastSuccessfulCommunication() { return getSafe(() -> podState.getLastSuccessfulCommunication()); } + /** + * Does not automatically store pod state in order to decrease I/O load + */ public final void setLastSuccessfulCommunication(DateTime dateTime) { - setAndStore(() -> podState.setLastSuccessfulCommunication(dateTime)); + setSafe(() -> podState.setLastSuccessfulCommunication(dateTime)); } public final DateTime getLastFailedCommunication() { return getSafe(() -> podState.getLastFailedCommunication()); } + /** + * Does not automatically store pod state in order to decrease I/O load + */ public final void setLastFailedCommunication(DateTime dateTime) { - setAndStore(() -> podState.setLastFailedCommunication(dateTime)); + setSafe(() -> podState.setLastFailedCommunication(dateTime)); } - public final DateTime getLastUpdatedFromStatusResponse() { - return getSafe(() -> podState.getLastUpdatedFromStatusResponse()); + public final DateTime getLastUpdatedFromResponse() { + return getSafe(() -> podState.getLastUpdatedFromResponse()); } + /** + * @return true if the Pod State contains a fault event. Is the Pod state does not contain + * a fault event, this does NOT necessarily mean that the Pod is not faulted. For a reliable + * indication on whether or not the pod is faulted, see {@link #isPodFaulted() isPodFaulted()} + */ public final boolean hasFaultEvent() { return podState != null && podState.getFaultEvent() != null; } @@ -302,7 +328,9 @@ public abstract class PodStateManager { return getSafe(() -> podState.getReservoirLevel()); } - public final Double getTotalInsulinDelivered() { return getSafe(() -> podState.getTotalInsulinDelivered()); } + public final Double getTotalInsulinDelivered() { + return getSafe(() -> podState.getTotalInsulinDelivered()); + } public final Duration getScheduleOffset() { DateTime now = getTime(); @@ -325,80 +353,164 @@ public abstract class PodStateManager { return getSafe(() -> podState.getLastBolusAmount()); } - public final void setLastBolus(DateTime startTime, double amount) { + public final Duration getLastBolusDuration() { + return getSafe(() -> podState.getLastBolusDuration()); + } + + public final boolean isLastBolusCertain() { + Boolean certain = getSafe(() -> podState.isLastBolusCertain()); + return certain == null || certain; + } + + public final void setLastBolus(DateTime startTime, double amount, Duration duration, boolean certain) { setAndStore(() -> { podState.setLastBolusStartTime(startTime); podState.setLastBolusAmount(amount); + podState.setLastBolusDuration(duration); + podState.setLastBolusCertain(certain); }); } - public final DateTime getLastTempBasalStartTime() { - return getSafe(() -> podState.getLastTempBasalStartTime()); + public final boolean hasLastBolus() { + return getLastBolusAmount() != null && getLastBolusDuration() != null && getLastBolusStartTime() != null; } - public final Double getLastTempBasalAmount() { - return getSafe(() -> podState.getLastTempBasalAmount()); + public final DateTime getTempBasalStartTime() { + return getSafe(() -> podState.getTempBasalStartTime()); } - public final Duration getLastTempBasalDuration() { - return getSafe(() -> podState.getLastTempBasalDuration()); + public final Double getTempBasalAmount() { + return getSafe(() -> podState.getTempBasalAmount()); } - public final void setLastTempBasal(DateTime startTime, Double amount, Duration duration) { - setAndStore(() -> { - podState.setLastTempBasalStartTime(startTime); - podState.setLastTempBasalAmount(amount); - podState.setLastTempBasalDuration(duration); - }); + public final Duration getTempBasalDuration() { + return getSafe(() -> podState.getTempBasalDuration()); + } + + public final boolean isTempBasalCertain() { + Boolean certain = getSafe(() -> podState.isTempBasalCertain()); + return certain == null || certain; + } + + 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, Boolean certain, boolean store) { + DateTime currentStartTime = getTempBasalStartTime(); + Double currentAmount = getTempBasalAmount(); + Duration currentDuration = getTempBasalDuration(); + if (!Objects.equals(currentStartTime, startTime) || !Objects.equals(currentAmount, amount) || !Objects.equals(currentDuration, duration)) { + Runnable runnable = () -> { + podState.setTempBasalStartTime(startTime); + podState.setTempBasalAmount(amount); + podState.setTempBasalDuration(duration); + podState.setTempBasalCertain(certain); + }; + + if (store) { + setAndStore(runnable); + } else { + setSafe(runnable); + } + onTbrChanged(); + } + } + + /** + * @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 + * a temp basal is actually running, use {@link #isTempBasalRunning() isTempBasalRunning()} + */ + public final boolean hasTempBasal() { + return getTempBasalAmount() != null && getTempBasalDuration() != null && getTempBasalStartTime() != null; + } + + /** + * @return true when a Temp Basal is stored in the Pod Stated and this temp basal is currently running (based on start time and duration) + */ + public final boolean isTempBasalRunning() { + if (hasTempBasal()) { + DateTime tempBasalEndTime = getTempBasalStartTime().plus(getTempBasalDuration()); + return DateTime.now().isBefore(tempBasalEndTime); + } + return false; } public final DeliveryStatus getLastDeliveryStatus() { return getSafe(() -> podState.getLastDeliveryStatus()); } - public final void updateFromStatusResponse(StatusResponse statusResponse) { - if (!hasPodState()) { - throw new IllegalStateException("Cannot update from status response: podState is null"); - } - setAndStore(() -> { + public final Duration getExpirationAlertTimeBeforeShutdown() { + return getSafe(() -> podState.getExpirationAlertTimeBeforeShutdown()); + } + + public final void setExpirationAlertTimeBeforeShutdown(Duration duration) { + setAndStore(() -> podState.setExpirationAlertTimeBeforeShutdown(duration)); + } + + public final Integer getLowReservoirAlertUnits() { + return getSafe(() -> podState.getLowReservoirAlertUnits()); + } + + public final void setLowReservoirAlertUnits(Integer units) { + setAndStore(() -> podState.setLowReservoirAlertUnits(units)); + } + + /** + * Does not automatically store pod state in order to decrease I/O load + */ + public final void updateFromResponse(StatusUpdatableResponse statusResponse) { + setSafe(() -> { if (podState.getActivatedAt() == null) { DateTime activatedAtCalculated = getTime().minus(statusResponse.getTimeActive()); podState.setActivatedAt(activatedAtCalculated); } DateTime expiresAt = podState.getExpiresAt(); - DateTime expiresAtCalculated = podState.getActivatedAt().plus(OmnipodConst.NOMINAL_POD_LIFE); + DateTime expiresAtCalculated = podState.getActivatedAt().plus(OmnipodConstants.NOMINAL_POD_LIFE); if (expiresAt == null || expiresAtCalculated.isBefore(expiresAt) || expiresAtCalculated.isAfter(expiresAt.plusMinutes(1))) { podState.setExpiresAt(expiresAtCalculated); } podState.setSuspended(statusResponse.getDeliveryStatus() == DeliveryStatus.SUSPENDED); - podState.setActiveAlerts(statusResponse.getAlerts()); + podState.setActiveAlerts(statusResponse.getUnacknowledgedAlerts()); podState.setLastDeliveryStatus(statusResponse.getDeliveryStatus()); podState.setReservoirLevel(statusResponse.getReservoirLevel()); podState.setTotalTicksDelivered(statusResponse.getTicksDelivered()); podState.setPodProgressStatus(statusResponse.getPodProgressStatus()); - podState.setLastUpdatedFromStatusResponse(DateTime.now()); + if (statusResponse.getDeliveryStatus().isTbrRunning()) { + if (!isTempBasalCertain() && isTempBasalRunning()) { + podState.setTempBasalCertain(true); + } + } else { + // Triggers {@link #onTbrChanged() onTbrChanged()} when appropriate + setTempBasal(null, null, null, true, false); + } + podState.setLastUpdatedFromResponse(DateTime.now()); }); } - private void setAndStore(Runnable runnable) { - setAndStore(runnable, true); + protected void onTbrChanged() { + // Deliberately left empty + // Can be overridden in subclasses } - private void setAndStore(Runnable runnable, boolean notifyPodStateChanged) { + private void setAndStore(Runnable runnable) { + setSafe(runnable); + storePodState(); + } + + // Not actually "safe" as it throws an Exception, but it prevents NPEs + private void setSafe(Runnable runnable) { if (!hasPodState()) { throw new IllegalStateException("Cannot mutate PodState: podState is null"); } runnable.run(); - storePodState(); - if (notifyPodStateChanged) { - notifyPodStateChanged(); - } } - private void storePodState() { + public void storePodState() { String podState = gsonInstance.toJson(this.podState); - aapsLogger.info(LTag.PUMP, "storePodState: storing podState: " + podState); + aapsLogger.debug(LTag.PUMP, "storePodState: storing podState: {}", podState); storePodState(podState); } @@ -422,12 +534,8 @@ public abstract class PodStateManager { aapsLogger.error(LTag.PUMP, "loadPodState: could not deserialize PodState: " + storedPodState, ex); } } - - notifyPodStateChanged(); } - protected abstract void notifyPodStateChanged(); - // Not actually "safe" as it throws an Exception, but it prevents NPEs private T getSafe(Supplier supplier) { if (!hasPodState()) { @@ -466,7 +574,7 @@ public abstract class PodStateManager { private int messageNumber; private DateTime lastSuccessfulCommunication; private DateTime lastFailedCommunication; - private DateTime lastUpdatedFromStatusResponse; + private DateTime lastUpdatedFromResponse; private DateTimeZone timeZone; private DateTime activatedAt; private DateTime expiresAt; @@ -481,9 +589,14 @@ public abstract class PodStateManager { private BasalSchedule basalSchedule; private DateTime lastBolusStartTime; private Double lastBolusAmount; - private Double lastTempBasalAmount; - private DateTime lastTempBasalStartTime; - private Duration lastTempBasalDuration; + private Duration lastBolusDuration; + private Boolean lastBolusCertain; + private Double tempBasalAmount; + private DateTime tempBasalStartTime; + private Duration tempBasalDuration; + private Boolean tempBasalCertain; + private Duration expirationAlertTimeBeforeShutdown; + private Integer lowReservoirAlertUnits; private final Map configuredAlerts = new HashMap<>(); private PodState(int address) { @@ -558,12 +671,12 @@ public abstract class PodStateManager { this.lastFailedCommunication = lastFailedCommunication; } - DateTime getLastUpdatedFromStatusResponse() { - return lastUpdatedFromStatusResponse; + DateTime getLastUpdatedFromResponse() { + return lastUpdatedFromResponse; } - void setLastUpdatedFromStatusResponse(DateTime lastUpdatedFromStatusResponse) { - this.lastUpdatedFromStatusResponse = lastUpdatedFromStatusResponse; + void setLastUpdatedFromResponse(DateTime lastUpdatedFromResponse) { + this.lastUpdatedFromResponse = lastUpdatedFromResponse; } DateTimeZone getTimeZone() { @@ -610,17 +723,19 @@ public abstract class PodStateManager { return totalTicksDelivered; } - public Double getTotalInsulinDelivered() { + Double getTotalInsulinDelivered() { if (totalTicksDelivered != null) { - return totalTicksDelivered * OmnipodConst.POD_PULSE_SIZE; + return totalTicksDelivered * OmnipodConstants.POD_PULSE_SIZE; } else { return null; } } - void setTotalTicksDelivered(Integer totalTicksDelivered) { this.totalTicksDelivered = totalTicksDelivered; } + void setTotalTicksDelivered(Integer totalTicksDelivered) { + this.totalTicksDelivered = totalTicksDelivered; + } - public boolean isSuspended() { + boolean isSuspended() { return suspended; } @@ -636,7 +751,7 @@ public abstract class PodStateManager { this.nonceState = nonceState; } - public PodProgressStatus getPodProgressStatus() { + PodProgressStatus getPodProgressStatus() { return podProgressStatus; } @@ -668,7 +783,7 @@ public abstract class PodStateManager { this.basalSchedule = basalSchedule; } - public DateTime getLastBolusStartTime() { + DateTime getLastBolusStartTime() { return lastBolusStartTime; } @@ -684,34 +799,74 @@ public abstract class PodStateManager { this.lastBolusAmount = lastBolusAmount; } - Double getLastTempBasalAmount() { - return lastTempBasalAmount; + Duration getLastBolusDuration() { + return lastBolusDuration; } - void setLastTempBasalAmount(Double lastTempBasalAmount) { - this.lastTempBasalAmount = lastTempBasalAmount; + void setLastBolusDuration(Duration lastBolusDuration) { + this.lastBolusDuration = lastBolusDuration; } - DateTime getLastTempBasalStartTime() { - return lastTempBasalStartTime; + Boolean isLastBolusCertain() { + return lastBolusCertain; } - void setLastTempBasalStartTime(DateTime lastTempBasalStartTime) { - this.lastTempBasalStartTime = lastTempBasalStartTime; + void setLastBolusCertain(Boolean certain) { + this.lastBolusCertain = certain; } - Duration getLastTempBasalDuration() { - return lastTempBasalDuration; + Double getTempBasalAmount() { + return tempBasalAmount; } - void setLastTempBasalDuration(Duration lastTempBasalDuration) { - this.lastTempBasalDuration = lastTempBasalDuration; + void setTempBasalAmount(Double tempBasalAmount) { + this.tempBasalAmount = tempBasalAmount; + } + + DateTime getTempBasalStartTime() { + return tempBasalStartTime; + } + + void setTempBasalStartTime(DateTime tempBasalStartTime) { + this.tempBasalStartTime = tempBasalStartTime; + } + + Duration getTempBasalDuration() { + return tempBasalDuration; + } + + void setTempBasalDuration(Duration tempBasalDuration) { + this.tempBasalDuration = tempBasalDuration; + } + + Boolean isTempBasalCertain() { + return tempBasalCertain; + } + + void setTempBasalCertain(Boolean certain) { + this.tempBasalCertain = certain; } Map getConfiguredAlerts() { return configuredAlerts; } + Duration getExpirationAlertTimeBeforeShutdown() { + return expirationAlertTimeBeforeShutdown; + } + + void setExpirationAlertTimeBeforeShutdown(Duration duration) { + expirationAlertTimeBeforeShutdown = duration; + } + + Integer getLowReservoirAlertUnits() { + return lowReservoirAlertUnits; + } + + void setLowReservoirAlertUnits(Integer units) { + lowReservoirAlertUnits = units; + } + @Override public String toString() { return "PodState{" + "address=" + address + @@ -723,12 +878,13 @@ public abstract class PodStateManager { ", messageNumber=" + messageNumber + ", lastSuccessfulCommunication=" + lastSuccessfulCommunication + ", lastFailedCommunication=" + lastFailedCommunication + - ", lastUpdatedFromStatusResponse=" + lastUpdatedFromStatusResponse + + ", lastUpdatedFromResponse=" + lastUpdatedFromResponse + ", timeZone=" + timeZone + ", activatedAt=" + activatedAt + ", expiresAt=" + expiresAt + ", faultEvent=" + faultEvent + ", reservoirLevel=" + reservoirLevel + + ", totalTicksDelivered=" + totalTicksDelivered + ", suspended=" + suspended + ", nonceState=" + nonceState + ", podProgressStatus=" + podProgressStatus + @@ -737,9 +893,14 @@ public abstract class PodStateManager { ", basalSchedule=" + basalSchedule + ", lastBolusStartTime=" + lastBolusStartTime + ", lastBolusAmount=" + lastBolusAmount + - ", lastTempBasalAmount=" + lastTempBasalAmount + - ", lastTempBasalStartTime=" + lastTempBasalStartTime + - ", lastTempBasalDuration=" + lastTempBasalDuration + + ", lastBolusDuration=" + lastBolusDuration + + ", lastBolusCertain=" + lastBolusCertain + + ", tempBasalAmount=" + tempBasalAmount + + ", tempBasalStartTime=" + tempBasalStartTime + + ", tempBasalDuration=" + tempBasalDuration + + ", tempBasalCertain=" + tempBasalCertain + + ", expirationAlertHoursBeforeShutdown=" + expirationAlertTimeBeforeShutdown + + ", lowReservoirAlertUnits=" + lowReservoirAlertUnits + ", configuredAlerts=" + configuredAlerts + '}'; } @@ -776,7 +937,7 @@ public abstract class PodStateManager { return (int) ((table[1] + (table[0] << 16)) & 0xFFFFFFFFL); } - public int getCurrentNonce() { + int getCurrentNonce() { return (int) table[(2 + index)]; } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/SetupActionResult.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/SetupActionResult.java similarity index 88% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/SetupActionResult.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/SetupActionResult.java index 439aeedbae..867c56aa9f 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/SetupActionResult.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/SetupActionResult.java @@ -1,6 +1,6 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.manager; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodProgressStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; public class SetupActionResult { private final ResultType resultType; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/ui/OmnipodUIComm.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/ui/OmnipodUIComm.java deleted file mode 100644 index d39559e4b5..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/ui/OmnipodUIComm.java +++ /dev/null @@ -1,57 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.driver.ui; - -import dagger.android.HasAndroidInjector; -import info.nightscout.androidaps.logging.AAPSLogger; -import info.nightscout.androidaps.logging.LTag; -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.data.RLHistoryItemOmnipod; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.IOmnipodManager; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodCommandType; - -/** - * Created by andy on 4.8.2019 - */ -public class OmnipodUIComm { - - private final HasAndroidInjector injector; - private final AAPSLogger aapsLogger; - private final OmnipodUIPostprocessor omnipodUIPostprocessor; - private final IOmnipodManager omnipodCommunicationManager; - private RileyLinkUtil rileyLinkUtil; - - public OmnipodUIComm( - HasAndroidInjector injector, - AAPSLogger aapsLogger, - OmnipodUIPostprocessor omnipodUIPostprocessor, - IOmnipodManager omnipodCommunicationManager, - RileyLinkUtil rileyLinkUtil - ) { - this.injector = injector; - this.aapsLogger = aapsLogger; - this.omnipodUIPostprocessor = omnipodUIPostprocessor; - this.omnipodCommunicationManager = omnipodCommunicationManager; - this.rileyLinkUtil = rileyLinkUtil; - } - - - public OmnipodUITask executeCommand(OmnipodCommandType commandType, Object... parameters) { - - aapsLogger.warn(LTag.PUMP, "Execute Command: " + commandType.name()); - - OmnipodUITask task = new OmnipodUITask(injector, commandType, parameters); - - rileyLinkUtil.getRileyLinkHistory().add(new RLHistoryItemOmnipod(commandType)); - - task.execute(this.omnipodCommunicationManager); - - if (!task.isReceived()) { - aapsLogger.warn(LTag.PUMP, "Reply not received for " + commandType); - } - - task.postProcess(omnipodUIPostprocessor); - - return task; - - } - -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/ui/OmnipodUIPostprocessor.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/ui/OmnipodUIPostprocessor.java deleted file mode 100644 index 33d734bdde..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/ui/OmnipodUIPostprocessor.java +++ /dev/null @@ -1,64 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.driver.ui; - -import java.util.Date; - -import javax.inject.Inject; -import javax.inject.Singleton; - -import info.nightscout.androidaps.data.DetailedBolusInfo; -import info.nightscout.androidaps.data.PumpEnactResult; -import info.nightscout.androidaps.logging.AAPSLogger; -import info.nightscout.androidaps.logging.LTag; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus; - -/** - * Created by andy on 4.8.2019 - */ -// TODO remove once OmnipodPumpStatus has been removed -@Singleton -public class OmnipodUIPostprocessor { - private final AAPSLogger aapsLogger; - private final OmnipodPumpStatus pumpStatus; - - @Inject - public OmnipodUIPostprocessor(AAPSLogger aapsLogger, OmnipodPumpStatus pumpStatus) { - this.aapsLogger = aapsLogger; - this.pumpStatus = pumpStatus; - } - - // this is mostly intended for command that return certain statuses (Remaining Insulin, ...), and - // where responses won't be directly used - public void postProcessData(OmnipodUITask uiTask) { - - switch (uiTask.commandType) { - case SetBolus: - if (uiTask.returnData != null) { - - PumpEnactResult result = uiTask.returnData; - - DetailedBolusInfo detailedBolusInfo = (DetailedBolusInfo) uiTask.getObjectFromParameters(0); - - if (result.success) { - boolean isSmb = detailedBolusInfo.isSMB; - - if (!isSmb) { - pumpStatus.lastBolusAmount = detailedBolusInfo.insulin; - pumpStatus.lastBolusTime = new Date(); - } - } - } - break; - - case CancelTemporaryBasal: - pumpStatus.tempBasalStart = 0; - pumpStatus.tempBasalEnd = 0; - pumpStatus.tempBasalAmount = null; - pumpStatus.tempBasalLength = null; - break; - - default: - aapsLogger.debug(LTag.PUMP, "Post-processing not implemented for {}.", uiTask.commandType.name()); - - } - } -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/ui/OmnipodUITask.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/ui/OmnipodUITask.java deleted file mode 100644 index 140f1de335..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/ui/OmnipodUITask.java +++ /dev/null @@ -1,231 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.driver.ui; - -import javax.inject.Inject; - -import dagger.android.HasAndroidInjector; -import info.nightscout.androidaps.data.DetailedBolusInfo; -import info.nightscout.androidaps.data.Profile; -import info.nightscout.androidaps.data.PumpEnactResult; -import info.nightscout.androidaps.logging.AAPSLogger; -import info.nightscout.androidaps.logging.LTag; -import info.nightscout.androidaps.plugins.bus.RxBusWrapper; -import info.nightscout.androidaps.plugins.pump.common.data.TempBasalPair; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.IOmnipodManager; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.OmnipodCommandType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInitActionType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInitReceiver; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodResponseType; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil; - -/** - * Created by andy on 4.8.2019 - */ - -public class OmnipodUITask { - - @Inject RxBusWrapper rxBus; - @Inject AAPSLogger aapsLogger; - @Inject OmnipodPumpStatus omnipodPumpStatus; - @Inject OmnipodUtil omnipodUtil; - - private final HasAndroidInjector injector; - - public OmnipodCommandType commandType; - public PumpEnactResult returnData; - private String errorDescription; - private Object[] parameters; - public PodResponseType responseType; - public Object returnDataObject; - - - public OmnipodUITask(HasAndroidInjector injector, OmnipodCommandType commandType) { - this.injector = injector; - this.injector.androidInjector().inject(this); - this.commandType = commandType; - } - - - public OmnipodUITask(HasAndroidInjector injector, OmnipodCommandType commandType, Object... parameters) { - this.injector = injector; - this.injector.androidInjector().inject(this); - this.commandType = commandType; - this.parameters = parameters; - } - - - public void execute(IOmnipodManager communicationManager) { - - - aapsLogger.debug(LTag.PUMP, "OmnipodUITask: @@@ In execute. {}", commandType); - - switch (commandType) { - - case PairAndPrimePod: - returnData = communicationManager.initPod((PodInitActionType) parameters[0], (PodInitReceiver) parameters[1], null); - break; - - case FillCanulaAndSetBasalProfile: - returnData = communicationManager.initPod((PodInitActionType) parameters[0], (PodInitReceiver) parameters[1], (Profile) parameters[2]); - break; - - case DeactivatePod: - returnData = communicationManager.deactivatePod((PodInitReceiver) parameters[0]); - break; - - case ResetPodStatus: - returnData = communicationManager.resetPodStatus(); - break; - - case SetBasalProfile: - returnData = communicationManager.setBasalProfile((Profile) parameters[0]); - break; - - case SetBolus: { - DetailedBolusInfo detailedBolusInfo = (DetailedBolusInfo) parameters[0]; - - if (detailedBolusInfo != null) - returnData = communicationManager.setBolus(detailedBolusInfo); - } - break; - - case GetPodPulseLog: - // This command is very error prone, so retry a few times if it fails - // Can take some time, but that's ok since this is a very specific feature for experts - // And will not be used by normal users - for (int i = 0; 3 > i; i++) { - try { - returnDataObject = communicationManager.readPulseLog(); - responseType = PodResponseType.Acknowledgment; - break; - } catch (Exception ex) { - { - aapsLogger.warn(LTag.PUMP, "Failed to retrieve pulse log", ex); - } - returnDataObject = null; - responseType = PodResponseType.Error; - } - } - break; - - case GetPodStatus: - returnData = communicationManager.getPodStatus(); - break; - - case CancelBolus: - returnData = communicationManager.cancelBolus(); - break; - - case SetTemporaryBasal: { - TempBasalPair tbr = getTBRSettings(); - if (tbr != null) { - returnData = communicationManager.setTemporaryBasal(tbr); - } - } - break; - - case CancelTemporaryBasal: - returnData = communicationManager.cancelTemporaryBasal(); - break; - - case AcknowledgeAlerts: - returnData = communicationManager.acknowledgeAlerts(); - break; - - case SetTime: - returnData = communicationManager.setTime(); - break; - - default: { - aapsLogger.warn(LTag.PUMP, "This commandType is not supported (yet) - {}.", commandType); - responseType = PodResponseType.Error; - } - - } - - if (returnData != null) { - responseType = returnData.success ? PodResponseType.Acknowledgment : PodResponseType.Error; - } - - } - - - private TempBasalPair getTBRSettings() { - return new TempBasalPair(getDoubleFromParameters(0), // - false, // - getIntegerFromParameters(1)); - } - - - private Float getFloatFromParameters(int index) { - return (Float) parameters[index]; - } - - public Object getObjectFromParameters(int index) { - return parameters[index]; - } - - public Double getDoubleFromParameters(int index) { - return (Double) parameters[index]; - } - - public boolean getBooleanFromParameters(int index) { - return (boolean) parameters[index]; - } - - public Integer getIntegerFromParameters(int index) { - return (Integer) parameters[index]; - } - - - public T getResult() { - return (T) returnData; - } - - - public boolean isReceived() { - return (returnData != null || errorDescription != null); - } - - - // FIXME remove once OmnipodPumpStatus has been removed - public void postProcess(OmnipodUIPostprocessor postprocessor) { - - aapsLogger.debug(LTag.PUMP, "OmnipodUITask: @@@ postProcess. {}", commandType); - aapsLogger.debug(LTag.PUMP, "OmnipodUITask: @@@ postProcess. responseType={}", responseType); - - if (responseType == PodResponseType.Data || responseType == PodResponseType.Acknowledgment) { - postprocessor.postProcessData(this); - } - - aapsLogger.debug(LTag.PUMP, "OmnipodUITask: @@@ postProcess. responseType={}", responseType); - - if (!responseType.isError()) { - omnipodPumpStatus.setLastCommunicationToNow(); - } - } - - - public boolean hasData() { - return (responseType == PodResponseType.Data || responseType == PodResponseType.Acknowledgment); - } - - - public Object getParameter(int index) { - return parameters[index]; - } - - - public PodResponseType getResponseType() { - return this.responseType; - } - - public boolean wasCommandSuccessful() { - if (returnData == null) { - return false; - } - return returnData.success; - } - - -} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/AlertConfigurationFactory.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/util/AlertConfigurationUtil.java similarity index 65% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/AlertConfigurationFactory.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/util/AlertConfigurationUtil.java index 400fe18875..0d223458d6 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/defs/AlertConfigurationFactory.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/util/AlertConfigurationUtil.java @@ -1,21 +1,29 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.defs; +package info.nightscout.androidaps.plugins.pump.omnipod.driver.util; import org.joda.time.Duration; -public class AlertConfigurationFactory { - public static AlertConfiguration createLowReservoirAlertConfiguration(Double units) { - return new AlertConfiguration(AlertType.LOW_RESERVOIR_ALERT, AlertSlot.SLOT4, true, false, Duration.ZERO, +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertConfiguration; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertSlot; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.BeepRepeat; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.BeepType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.TimerAlertTrigger; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.UnitsRemainingAlertTrigger; + +public class AlertConfigurationUtil { + public static AlertConfiguration createLowReservoirAlertConfiguration(boolean active, Double units) { + return new AlertConfiguration(AlertType.LOW_RESERVOIR_ALERT, AlertSlot.SLOT4, active, false, Duration.ZERO, new UnitsRemainingAlertTrigger(units), BeepType.BIP_BEEP_BIP_BEEP_BIP_BEEP_BIP_BEEP, BeepRepeat.EVERY_MINUTE_FOR_3_MINUTES_REPEAT_EVERY_60_MINUTES); } - public static AlertConfiguration createExpirationAdvisoryAlertConfiguration(Duration timeUntilAlert, Duration duration) { - return new AlertConfiguration(AlertType.EXPIRATION_ADVISORY_ALERT, AlertSlot.SLOT7, true, false, duration, - new TimerAlertTrigger(timeUntilAlert), BeepType.BIP_BEEP_BIP_BEEP_BIP_BEEP_BIP_BEEP, BeepRepeat.EVERY_MINUTE_FOR_3_MINUTES_REPEAT_EVERY_15_MINUTES); + public static AlertConfiguration createExpirationAdvisoryAlertConfiguration(boolean active, Duration timeUntilAlert, Duration duration) { + return new AlertConfiguration(AlertType.EXPIRATION_ADVISORY_ALERT, AlertSlot.SLOT7, active, false, duration, + new TimerAlertTrigger(timeUntilAlert), BeepType.BIP_BEEP_BIP_BEEP_BIP_BEEP_BIP_BEEP, BeepRepeat.EVERY_15_MINUTES); } public static AlertConfiguration createShutdownImminentAlertConfiguration(Duration timeUntilAlert) { return new AlertConfiguration(AlertType.SHUTDOWN_IMMINENT_ALARM, AlertSlot.SLOT2, true, false, Duration.ZERO, - new TimerAlertTrigger(timeUntilAlert), BeepType.BIP_BEEP_BIP_BEEP_BIP_BEEP_BIP_BEEP, BeepRepeat.EVERY_15_MINUTES); + new TimerAlertTrigger(timeUntilAlert), BeepType.BIP_BEEP_BIP_BEEP_BIP_BEEP_BIP_BEEP, BeepRepeat.EVERY_MINUTE_FOR_3_MINUTES_REPEAT_EVERY_15_MINUTES); } public static AlertConfiguration createAutoOffAlertConfiguration(boolean active, Duration countdownDuration) { diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/events/EventOmnipodPumpValuesChanged.kt b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/event/EventOmnipodPumpValuesChanged.kt similarity index 68% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/events/EventOmnipodPumpValuesChanged.kt rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/event/EventOmnipodPumpValuesChanged.kt index 5b0f03a241..e54d7455dd 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/events/EventOmnipodPumpValuesChanged.kt +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/event/EventOmnipodPumpValuesChanged.kt @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.events +package info.nightscout.androidaps.plugins.pump.omnipod.event import info.nightscout.androidaps.events.Event diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/event/EventOmnipodTbrChanged.kt b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/event/EventOmnipodTbrChanged.kt new file mode 100644 index 0000000000..2b212506cd --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/event/EventOmnipodTbrChanged.kt @@ -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 EventOmnipodTbrChanged : Event() \ No newline at end of file diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/events/EventOmnipodAcknowledgeAlertsChanged.kt b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/events/EventOmnipodAcknowledgeAlertsChanged.kt deleted file mode 100644 index 0bc2b5dc4b..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/events/EventOmnipodAcknowledgeAlertsChanged.kt +++ /dev/null @@ -1,9 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.events - -import info.nightscout.androidaps.events.Event - -/** - * Created by andy on 04.06.2018. - */ -// FIXME can be removed, we should just use EventOmnipodPumpValuesChanged -class EventOmnipodAcknowledgeAlertsChanged : Event() \ No newline at end of file diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/events/EventOmnipodRefreshButtonState.kt b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/events/EventOmnipodRefreshButtonState.kt deleted file mode 100644 index 9ad6f2129e..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/events/EventOmnipodRefreshButtonState.kt +++ /dev/null @@ -1,5 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.events - -import info.nightscout.androidaps.events.Event - -class EventOmnipodRefreshButtonState(val newState: Boolean) : Event() \ No newline at end of file diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/manager/AapsOmnipodManager.java similarity index 51% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/manager/AapsOmnipodManager.java index bd657d3043..9ce1e2a2a5 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/comm/AapsOmnipodManager.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/manager/AapsOmnipodManager.java @@ -1,7 +1,6 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.driver.comm; +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; @@ -14,7 +13,6 @@ 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; @@ -24,7 +22,6 @@ import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.events.Event; import info.nightscout.androidaps.interfaces.ActivePluginProvider; import info.nightscout.androidaps.interfaces.DatabaseHelperInterface; -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; @@ -35,72 +32,82 @@ import info.nightscout.androidaps.plugins.general.overview.notifications.Notific import info.nightscout.androidaps.plugins.pump.common.data.TempBasalPair; import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil; import info.nightscout.androidaps.plugins.pump.omnipod.R; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodManager; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.SetupActionResult; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.ActionInitializationException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.CommandInitializationException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.CommunicationException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.CrcMismatchException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalDeliveryStatusException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalMessageAddressException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalMessageSequenceNumberException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalPacketTypeException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalPodProgressException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalResponseException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalVersionResponseTypeException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.MessageDecodingException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.NonceOutOfSyncException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.NonceResyncException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.NotEnoughDataException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.PodFaultException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.PodReturnedErrorResponseException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoRecentPulseLog; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoResponse; import info.nightscout.androidaps.plugins.pump.omnipod.data.ActiveBolus; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.FaultEventCode; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.IOmnipodManager; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInitActionType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInitReceiver; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BasalSchedule; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.schedule.BasalScheduleEntry; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.db.PodHistoryEntryType; -import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil; +import info.nightscout.androidaps.plugins.pump.omnipod.definition.OmnipodStorageKeys; +import info.nightscout.androidaps.plugins.pump.omnipod.definition.PodHistoryEntryType; +import info.nightscout.androidaps.plugins.pump.omnipod.definition.PodInitActionType; +import info.nightscout.androidaps.plugins.pump.omnipod.definition.PodInitReceiver; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoRecentPulseLog; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertConfiguration; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.FaultEventCode; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalSchedule; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalScheduleEntry; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.ActionInitializationException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.CommandFailedAfterChangingDeliveryStatusException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.CommandInitializationException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.CommunicationException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.CrcMismatchException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.DeliveryStatusVerificationFailedException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalDeliveryStatusException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalMessageAddressException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalMessageSequenceNumberException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPacketTypeException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalResponseException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalVersionResponseTypeException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.MessageDecodingException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.NonceOutOfSyncException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.NonceResyncException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.NotEnoughDataException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.OmnipodException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.PodFaultException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.PodReturnedErrorResponseException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.OmnipodManager; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.SetupActionResult; +import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged; +import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; +import info.nightscout.androidaps.plugins.pump.omnipod.util.AapsOmnipodUtil; +import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodAlertUtil; import info.nightscout.androidaps.utils.resources.ResourceHelper; import info.nightscout.androidaps.utils.sharedPreferences.SP; import io.reactivex.disposables.Disposable; import io.reactivex.subjects.SingleSubject; @Singleton -public class AapsOmnipodManager implements IOmnipodManager { +public class AapsOmnipodManager { private final PodStateManager podStateManager; - private final OmnipodUtil omnipodUtil; + private final AapsOmnipodUtil aapsOmnipodUtil; private final AAPSLogger aapsLogger; private final RxBusWrapper rxBus; private final ResourceHelper resourceHelper; private final HasAndroidInjector injector; private final ActivePluginProvider activePlugin; - private final OmnipodPumpStatus pumpStatus; private final Context context; private final SP sp; - private final OmnipodManager delegate; - private DatabaseHelperInterface databaseHelper; + private final DatabaseHelperInterface databaseHelper; + private final OmnipodAlertUtil omnipodAlertUtil; + + private boolean basalBeepsEnabled; + private boolean bolusBeepsEnabled; + private boolean smbBeepsEnabled; + private boolean tbrBeepsEnabled; + private boolean suspendDeliveryButtonEnabled; + private boolean pulseLogButtonEnabled; + private boolean timeChangeEventEnabled; @Inject - public AapsOmnipodManager(OmnipodCommunicationManager communicationService, + public AapsOmnipodManager(OmnipodRileyLinkCommunicationManager communicationService, PodStateManager podStateManager, - OmnipodPumpStatus pumpStatus, - OmnipodUtil omnipodUtil, + AapsOmnipodUtil aapsOmnipodUtil, AAPSLogger aapsLogger, RxBusWrapper rxBus, SP sp, @@ -108,107 +115,135 @@ public class AapsOmnipodManager implements IOmnipodManager { HasAndroidInjector injector, ActivePluginProvider activePlugin, Context context, - DatabaseHelperInterface databaseHelper) { + DatabaseHelperInterface databaseHelper, + OmnipodAlertUtil omnipodAlertUtil) { if (podStateManager == null) { throw new IllegalArgumentException("Pod state manager can not be null"); } this.podStateManager = podStateManager; - this.omnipodUtil = omnipodUtil; + this.aapsOmnipodUtil = aapsOmnipodUtil; this.aapsLogger = aapsLogger; this.rxBus = rxBus; this.resourceHelper = resourceHelper; this.injector = injector; this.activePlugin = activePlugin; - this.pumpStatus = pumpStatus; this.context = context; this.databaseHelper = databaseHelper; this.sp = sp; + this.omnipodAlertUtil = omnipodAlertUtil; delegate = new OmnipodManager(aapsLogger, sp, communicationService, podStateManager); } - public PodStateManager getPodStateManager() { - return podStateManager; + @Inject + void onInit() { + // this cannot be done in the constructor, as sp is not populated at that time + reloadSettings(); } - @Override - public PumpEnactResult initPod(PodInitActionType podInitActionType, PodInitReceiver podInitReceiver, Profile profile) { - long time = System.currentTimeMillis(); - if (PodInitActionType.PairAndPrimeWizardStep.equals(podInitActionType)) { - try { - Disposable disposable = delegate.pairAndPrime().subscribe(res -> // - handleSetupActionResult(podInitActionType, podInitReceiver, res, time, null)); + public void reloadSettings() { + 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); + suspendDeliveryButtonEnabled = sp.getBoolean(OmnipodStorageKeys.Preferences.SUSPEND_DELIVERY_BUTTON_ENABLED, false); + pulseLogButtonEnabled = sp.getBoolean(OmnipodStorageKeys.Preferences.PULSE_LOG_BUTTON_ENABLED, false); + timeChangeEventEnabled = sp.getBoolean(OmnipodStorageKeys.Preferences.TIME_CHANGE_EVENT_ENABLED, true); + } - return new PumpEnactResult(injector).success(true).enacted(true); - } catch (Exception ex) { - String comment = handleAndTranslateException(ex); - podInitReceiver.returnInitTaskStatus(podInitActionType, false, comment); - addFailureToHistory(time, PodHistoryEntryType.PairAndPrime, comment); - return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); - } - } else if (PodInitActionType.FillCannulaSetBasalProfileWizardStep.equals(podInitActionType)) { - try { - BasalSchedule basalSchedule; - try { - basalSchedule = mapProfileToBasalSchedule(profile); - } catch (Exception ex) { - throw new CommandInitializationException("Basal profile mapping failed", ex); - } - Disposable disposable = delegate.insertCannula(basalSchedule).subscribe(res -> // - handleSetupActionResult(podInitActionType, podInitReceiver, res, time, profile)); - - rxBus.send(new EventDismissNotification(Notification.OMNIPOD_POD_NOT_ATTACHED)); - - return new PumpEnactResult(injector).success(true).enacted(true); - } catch (Exception ex) { - String comment = handleAndTranslateException(ex); - podInitReceiver.returnInitTaskStatus(podInitActionType, false, comment); - addFailureToHistory(time, PodHistoryEntryType.FillCannulaSetBasalProfile, comment); - return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); - } + public PumpEnactResult pairAndPrime(PodInitActionType podInitActionType, PodInitReceiver podInitReceiver) { + if (podInitActionType != PodInitActionType.PAIR_AND_PRIME_WIZARD_STEP) { + return new PumpEnactResult(injector).success(false).enacted(false).comment(getStringResource(R.string.omnipod_error_illegal_init_action_type, podInitActionType.name())); } - return new PumpEnactResult(injector).success(false).enacted(false).comment(getStringResource(R.string.omnipod_error_illegal_init_action_type, podInitActionType.name())); - } - - @Override - public PumpEnactResult getPodStatus() { - long time = System.currentTimeMillis(); try { - StatusResponse statusResponse = delegate.getPodStatus(); - addSuccessToHistory(time, PodHistoryEntryType.GetPodStatus, statusResponse); - return new PumpEnactResult(injector).success(true).enacted(false); + Disposable disposable = delegate.pairAndPrime().subscribe(res -> // + handleSetupActionResult(podInitActionType, podInitReceiver, res, System.currentTimeMillis(), null)); + + return new PumpEnactResult(injector).success(true).enacted(true); } catch (Exception ex) { String comment = handleAndTranslateException(ex); - addFailureToHistory(time, PodHistoryEntryType.GetPodStatus, comment); + podInitReceiver.returnInitTaskStatus(podInitActionType, false, comment); + addFailureToHistory(System.currentTimeMillis(), PodHistoryEntryType.PAIR_AND_PRIME, comment); + return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); + } + } + + public PumpEnactResult setInitialBasalScheduleAndInsertCannula(PodInitActionType podInitActionType, PodInitReceiver podInitReceiver, Profile profile) { + if (podInitActionType != PodInitActionType.FILL_CANNULA_SET_BASAL_PROFILE_WIZARD_STEP) { + return new PumpEnactResult(injector).success(false).enacted(false).comment(getStringResource(R.string.omnipod_error_illegal_init_action_type, podInitActionType.name())); + } + + try { + BasalSchedule basalSchedule; + try { + basalSchedule = mapProfileToBasalSchedule(profile); + } catch (Exception ex) { + throw new CommandInitializationException("Basal profile mapping failed", ex); + } + + Disposable disposable = delegate.insertCannula(basalSchedule, omnipodAlertUtil.getExpirationReminderTimeBeforeShutdown(), omnipodAlertUtil.getLowReservoirAlertUnits()).subscribe(res -> // + handleSetupActionResult(podInitActionType, podInitReceiver, res, System.currentTimeMillis(), profile)); + + rxBus.send(new EventDismissNotification(Notification.OMNIPOD_POD_NOT_ATTACHED)); + + cancelSuspendedFakeTbrIfExists(); + + return new PumpEnactResult(injector).success(true).enacted(true); + } catch (Exception ex) { + String comment = handleAndTranslateException(ex); + podInitReceiver.returnInitTaskStatus(podInitActionType, false, comment); + addFailureToHistory(PodHistoryEntryType.FILL_CANNULA_SET_BASAL_PROFILE, comment); + return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); + } + } + + public PumpEnactResult configureAlerts(List alertConfigurations) { + try { + StatusResponse statusResponse = delegate.configureAlerts(alertConfigurations); + addSuccessToHistory(PodHistoryEntryType.CONFIGURE_ALERTS, alertConfigurations); + return new PumpEnactResult(injector).success(true).enacted(false); + } catch (Exception ex) { + String comment = handleAndTranslateException(ex); + addFailureToHistory(PodHistoryEntryType.CONFIGURE_ALERTS, comment); + return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); + } + } + + public PumpEnactResult getPodStatus() { + try { + StatusResponse statusResponse = delegate.getPodStatus(); + addSuccessToHistory(PodHistoryEntryType.GET_POD_STATUS, statusResponse); + return new PumpEnactResult(injector).success(true).enacted(false); + } catch (Exception ex) { + String comment = handleAndTranslateException(ex); + addFailureToHistory(PodHistoryEntryType.GET_POD_STATUS, comment); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); } } - @Override public PumpEnactResult deactivatePod(PodInitReceiver podInitReceiver) { - long time = System.currentTimeMillis(); try { delegate.deactivatePod(); } catch (Exception ex) { String comment = handleAndTranslateException(ex); - podInitReceiver.returnInitTaskStatus(PodInitActionType.DeactivatePodWizardStep, false, comment); - addFailureToHistory(time, PodHistoryEntryType.DeactivatePod, comment); + podInitReceiver.returnInitTaskStatus(PodInitActionType.DEACTIVATE_POD_WIZARD_STEP, false, comment); + addFailureToHistory(PodHistoryEntryType.DEACTIVATE_POD, comment); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); } - reportImplicitlyCanceledTbr(); + addSuccessToHistory(PodHistoryEntryType.DEACTIVATE_POD, null); - addSuccessToHistory(time, PodHistoryEntryType.DeactivatePod, null); + createSuspendedFakeTbrIfNotExists(); - podInitReceiver.returnInitTaskStatus(PodInitActionType.DeactivatePodWizardStep, true, null); + podInitReceiver.returnInitTaskStatus(PodInitActionType.DEACTIVATE_POD_WIZARD_STEP, true, null); return new PumpEnactResult(injector).success(true).enacted(true); } - @Override public PumpEnactResult setBasalProfile(Profile profile) { - long time = System.currentTimeMillis(); + PodHistoryEntryType historyEntryType = podStateManager.isSuspended() ? PodHistoryEntryType.RESUME_DELIVERY : PodHistoryEntryType.SET_BASAL_SCHEDULE; + try { BasalSchedule basalSchedule; try { @@ -217,37 +252,55 @@ public class AapsOmnipodManager implements IOmnipodManager { throw new CommandInitializationException("Basal profile mapping failed", ex); } delegate.setBasalSchedule(basalSchedule, isBasalBeepsEnabled()); - // Because setting a basal profile actually suspends and then resumes delivery, TBR is implicitly cancelled - reportImplicitlyCanceledTbr(); - addSuccessToHistory(time, PodHistoryEntryType.SetBasalSchedule, profile.getBasalValues()); - } catch (Exception ex) { - if ((ex instanceof OmnipodException) && !((OmnipodException) ex).isCertainFailure()) { - reportImplicitlyCanceledTbr(); - addToHistory(time, PodHistoryEntryType.SetBasalSchedule, "Uncertain failure", false); - return new PumpEnactResult(injector).success(false).enacted(false).comment(getStringResource(R.string.omnipod_error_set_basal_failed_uncertain)); + + if (historyEntryType == PodHistoryEntryType.RESUME_DELIVERY) { + cancelSuspendedFakeTbrIfExists(); } + addSuccessToHistory(historyEntryType, profile.getBasalValues()); + } catch (CommandFailedAfterChangingDeliveryStatusException ex) { + createSuspendedFakeTbrIfNotExists(); + String comment = getStringResource(R.string.omnipod_error_set_basal_failed_delivery_suspended); + showNotification(Notification.FAILED_UDPATE_PROFILE, comment, Notification.URGENT, R.raw.boluserror); + addFailureToHistory(historyEntryType, comment); + return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); + } catch (DeliveryStatusVerificationFailedException ex) { + String comment; + if (ex.getExpectedStatus() == DeliveryStatus.SUSPENDED) { + // Happened when suspending delivery before setting the new profile + comment = getStringResource(R.string.omnipod_error_set_basal_failed_delivery_might_be_suspended); + } else { + // Happened when setting the new profile (after suspending delivery) + comment = getStringResource(R.string.omnipod_error_set_basal_might_have_failed_delivery_might_be_suspended); + } + showNotification(Notification.FAILED_UDPATE_PROFILE, comment, Notification.URGENT, R.raw.boluserror); + addFailureToHistory(historyEntryType, comment); + return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); + } catch (Exception ex) { String comment = handleAndTranslateException(ex); - reportImplicitlyCanceledTbr(); - addFailureToHistory(time, PodHistoryEntryType.SetBasalSchedule, comment); + showNotification(Notification.FAILED_UDPATE_PROFILE, comment, Notification.URGENT, R.raw.boluserror); + addFailureToHistory(historyEntryType, comment); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); } - return new PumpEnactResult(injector).success(true).enacted(true); - } - - @Override - public PumpEnactResult resetPodStatus() { - getPodStateManager().removeState(); - - reportImplicitlyCanceledTbr(); - - addSuccessToHistory(System.currentTimeMillis(), PodHistoryEntryType.ResetPodState, null); + rxBus.send(new EventDismissNotification(Notification.OMNIPOD_POD_SUSPENDED)); + showNotification(Notification.PROFILE_SET_OK, + resourceHelper.gs(R.string.profile_set_ok), + Notification.INFO, null); return new PumpEnactResult(injector).success(true).enacted(true); } - @Override - public PumpEnactResult setBolus(DetailedBolusInfo detailedBolusInfo) { + public PumpEnactResult discardPodState() { + podStateManager.discardState(); + + addSuccessToHistory(System.currentTimeMillis(), PodHistoryEntryType.RESET_POD_STATE, null); + + createSuspendedFakeTbrIfNotExists(); + + return new PumpEnactResult(injector).success(true).enacted(true); + } + + public PumpEnactResult bolus(DetailedBolusInfo detailedBolusInfo) { OmnipodManager.BolusCommandResult bolusCommandResult; boolean beepsEnabled = detailedBolusInfo.isSMB ? isSmbBeepsEnabled() : isBolusBeepsEnabled(); @@ -265,14 +318,17 @@ public class AapsOmnipodManager implements IOmnipodManager { bolusStarted = new Date(); } catch (Exception ex) { String comment = handleAndTranslateException(ex); - addFailureToHistory(System.currentTimeMillis(), PodHistoryEntryType.SetBolus, comment); + addFailureToHistory(System.currentTimeMillis(), PodHistoryEntryType.SET_BOLUS, comment); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); } if (OmnipodManager.CommandDeliveryStatus.UNCERTAIN_FAILURE.equals(bolusCommandResult.getCommandDeliveryStatus())) { // For safety reasons, we treat this as a bolus that has successfully been delivered, in order to prevent insulin overdose - - showErrorDialog(getStringResource(R.string.omnipod_bolus_failed_uncertain), R.raw.boluserror); + if (detailedBolusInfo.isSMB) { + showNotification(getStringResource(R.string.omnipod_bolus_failed_uncertain_smb, detailedBolusInfo.insulin), Notification.URGENT, R.raw.boluserror); + } else { + showNotification(getStringResource(R.string.omnipod_bolus_failed_uncertain), Notification.URGENT, R.raw.boluserror); + } } detailedBolusInfo.date = bolusStarted.getTime(); @@ -297,12 +353,17 @@ public class AapsOmnipodManager implements IOmnipodManager { // I discussed this with the AAPS team but nobody seems to care so we're stuck with this ugly workaround for now try { ActiveBolus activeBolus = ActiveBolus.fromDetailedBolusInfo(detailedBolusInfo); - sp.putString(OmnipodConst.Prefs.ActiveBolus, omnipodUtil.getGsonInstance().toJson(activeBolus)); + sp.putString(OmnipodStorageKeys.Preferences.ACTIVE_BOLUS, aapsOmnipodUtil.getGsonInstance().toJson(activeBolus)); aapsLogger.debug(LTag.PUMP, "Stored active bolus to SP for recovery"); } catch (Exception ex) { aapsLogger.error(LTag.PUMP, "Failed to store active bolus to SP", ex); } + // Bolus is already updated in Pod state. If this was an SMB, it could be that + // the user is looking at the Pod tab right now, so send an extra event + // (this is normally done in OmnipodPumpPlugin) + sendEvent(new EventOmnipodPumpValuesChanged()); + // Wait for the bolus to finish OmnipodManager.BolusDeliveryResult bolusDeliveryResult = bolusCommandResult.getDeliveryResultSubject().blockingGet(); @@ -311,12 +372,11 @@ public class AapsOmnipodManager implements IOmnipodManager { addBolusToHistory(detailedBolusInfo); - sp.remove(OmnipodConst.Prefs.ActiveBolus); + sp.remove(OmnipodStorageKeys.Preferences.ACTIVE_BOLUS); return new PumpEnactResult(injector).success(true).enacted(true).bolusDelivered(detailedBolusInfo.insulin); } - @Override public PumpEnactResult cancelBolus() { SingleSubject bolusCommandExecutionSubject = delegate.getBolusCommandExecutionSubject(); if (bolusCommandExecutionSubject != null) { @@ -328,7 +388,7 @@ public class AapsOmnipodManager implements IOmnipodManager { } else { aapsLogger.debug(LTag.PUMP, "Not cancelling bolus: bolus command failed"); String comment = getStringResource(R.string.omnipod_bolus_did_not_succeed); - addFailureToHistory(System.currentTimeMillis(), PodHistoryEntryType.CancelBolus, comment); + addFailureToHistory(System.currentTimeMillis(), PodHistoryEntryType.CANCEL_BOLUS, comment); return new PumpEnactResult(injector).success(true).enacted(false).comment(comment); } } @@ -339,12 +399,12 @@ public class AapsOmnipodManager implements IOmnipodManager { try { delegate.cancelBolus(isBolusBeepsEnabled()); aapsLogger.debug(LTag.PUMP, "Successfully cancelled bolus", i); - addSuccessToHistory(System.currentTimeMillis(), PodHistoryEntryType.CancelBolus, null); + addSuccessToHistory(System.currentTimeMillis(), PodHistoryEntryType.CANCEL_BOLUS, null); return new PumpEnactResult(injector).success(true).enacted(true); } catch (PodFaultException ex) { aapsLogger.debug(LTag.PUMP, "Successfully cancelled bolus (implicitly because of a Pod Fault)"); - showPodFaultErrorDialog(ex.getFaultEvent().getFaultEventCode(), null); - addSuccessToHistory(System.currentTimeMillis(), PodHistoryEntryType.CancelBolus, null); + showPodFaultNotification(ex.getFaultEvent().getFaultEventCode()); + addSuccessToHistory(System.currentTimeMillis(), PodHistoryEntryType.CANCEL_BOLUS, null); return new PumpEnactResult(injector).success(true).enacted(true); } catch (Exception ex) { aapsLogger.debug(LTag.PUMP, "Failed to cancel bolus", ex); @@ -352,136 +412,115 @@ public class AapsOmnipodManager implements IOmnipodManager { } } - addFailureToHistory(System.currentTimeMillis(), PodHistoryEntryType.CancelBolus, comment); + addFailureToHistory(System.currentTimeMillis(), PodHistoryEntryType.CANCEL_BOLUS, comment); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); } - @Override public PumpEnactResult setTemporaryBasal(TempBasalPair tempBasalPair) { - boolean beepsEnabled = isTempBasalBeepsEnabled(); - long time = System.currentTimeMillis(); + boolean beepsEnabled = isTbrBeepsEnabled(); try { delegate.setTemporaryBasal(PumpType.Insulet_Omnipod.determineCorrectBasalSize(tempBasalPair.getInsulinRate()), Duration.standardMinutes(tempBasalPair.getDurationMinutes()), beepsEnabled, beepsEnabled); - time = System.currentTimeMillis(); - } catch (Exception ex) { - if ((ex instanceof OmnipodException) && !((OmnipodException) ex).isCertainFailure()) { - addToHistory(time, PodHistoryEntryType.SetTemporaryBasal, "Uncertain failure", false); - return new PumpEnactResult(injector).success(false).enacted(false).comment(getStringResource(R.string.omnipod_error_set_temp_basal_failed_uncertain)); + } catch (CommandFailedAfterChangingDeliveryStatusException ex) { + String comment = getStringResource(R.string.omnipod_cancelled_old_tbr_failed_to_set_new); + addFailureToHistory(PodHistoryEntryType.SET_TEMPORARY_BASAL, comment); + showNotification(comment, Notification.URGENT, null); + return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); + } catch (DeliveryStatusVerificationFailedException ex) { + String comment; + if (ex.getExpectedStatus() == DeliveryStatus.TEMP_BASAL_RUNNING) { + // Happened after cancelling the old TBR, when attempting to set new TBR + + comment = getStringResource(R.string.omnipod_error_set_temp_basal_failed_old_tbr_cancelled_new_might_have_failed); + long pumpId = addFailureToHistory(PodHistoryEntryType.SET_TEMPORARY_BASAL, comment); + + // Assume that setting the temp basal succeeded here, because in case it didn't succeed, + // The next StatusResponse that we receive will allow us to recover from the wrong state + // as we can see that the delivery status doesn't actually show that a TBR is running + // If we would assume that the TBR didn't succeed, we couldn't properly recover upon the next StatusResponse, + // as we could only see that the Pod is running a TBR, but we don't know the rate and duration as + // the Pod doesn't provide this information + addTempBasalTreatment(System.currentTimeMillis(), pumpId, tempBasalPair); + } else { + // Happened when attempting to cancel the old TBR + comment = getStringResource(R.string.omnipod_error_set_temp_basal_failed_old_tbr_might_be_cancelled); + addFailureToHistory(PodHistoryEntryType.SET_TEMPORARY_BASAL, comment); } - String comment = handleAndTranslateException(ex); - addFailureToHistory(time, PodHistoryEntryType.SetTemporaryBasal, comment); + + showNotification(comment, Notification.URGENT, R.raw.boluserror); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); - } - - reportImplicitlyCanceledTbr(); - - long pumpId = addSuccessToHistory(time, PodHistoryEntryType.SetTemporaryBasal, tempBasalPair); - - pumpStatus.tempBasalStart = time; - pumpStatus.tempBasalAmount = tempBasalPair.getInsulinRate(); - pumpStatus.tempBasalLength = tempBasalPair.getDurationMinutes(); - pumpStatus.tempBasalEnd = DateTimeUtil.getTimeInFutureFromMinutes(time, tempBasalPair.getDurationMinutes()); - pumpStatus.tempBasalPumpId = pumpId; - - TemporaryBasal tempStart = new TemporaryBasal(injector) // - .date(time) // - .duration(tempBasalPair.getDurationMinutes()) // - .absolute(tempBasalPair.getInsulinRate()) // - .pumpId(pumpId) - .source(Source.PUMP); - - activePlugin.getActiveTreatments().addToHistoryTempBasal(tempStart); - - return new PumpEnactResult(injector).success(true).enacted(true); - } - - @Override - public PumpEnactResult cancelTemporaryBasal() { - long time = System.currentTimeMillis(); - try { - delegate.cancelTemporaryBasal(isTempBasalBeepsEnabled()); - addSuccessToHistory(time, PodHistoryEntryType.CancelTemporaryBasalForce, null); } catch (Exception ex) { String comment = handleAndTranslateException(ex); - addFailureToHistory(time, PodHistoryEntryType.CancelTemporaryBasalForce, comment); + addFailureToHistory(PodHistoryEntryType.SET_TEMPORARY_BASAL, comment); + return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); + } + + long pumpId = addSuccessToHistory(PodHistoryEntryType.SET_TEMPORARY_BASAL, tempBasalPair); + + addTempBasalTreatment(System.currentTimeMillis(), pumpId, tempBasalPair); + + return new PumpEnactResult(injector).success(true).enacted(true); + } + + public PumpEnactResult cancelTemporaryBasal() { + try { + delegate.cancelTemporaryBasal(isTbrBeepsEnabled()); + addSuccessToHistory(PodHistoryEntryType.CANCEL_TEMPORARY_BASAL, null); + } catch (Exception ex) { + String comment = handleAndTranslateException(ex); + addFailureToHistory(PodHistoryEntryType.CANCEL_TEMPORARY_BASAL, comment); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); } return new PumpEnactResult(injector).success(true).enacted(true); } - @Override public PumpEnactResult acknowledgeAlerts() { - long time = System.currentTimeMillis(); try { delegate.acknowledgeAlerts(); - addSuccessToHistory(time, PodHistoryEntryType.AcknowledgeAlerts, null); + addSuccessToHistory(PodHistoryEntryType.ACKNOWLEDGE_ALERTS, null); } catch (Exception ex) { String comment = handleAndTranslateException(ex); - addFailureToHistory(time, PodHistoryEntryType.AcknowledgeAlerts, comment); + addFailureToHistory(PodHistoryEntryType.ACKNOWLEDGE_ALERTS, comment); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); } return new PumpEnactResult(injector).success(true).enacted(true); } - // TODO should we add this to the OmnipodCommunicationManager interface? - public PumpEnactResult getPodInfo(PodInfoType podInfoType) { - long time = System.currentTimeMillis(); - try { - // TODO how can we return the PodInfo response? - // This method is useless unless we return the PodInfoResponse, - // because the pod state we keep, doesn't get updated from a PodInfoResponse. - // We use StatusResponses for that, which can be obtained from the getPodStatus method - PodInfoResponse podInfo = delegate.getPodInfo(podInfoType); - addSuccessToHistory(time, PodHistoryEntryType.GetPodInfo, podInfo); - return new PumpEnactResult(injector).success(true).enacted(true); - } catch (Exception ex) { - String comment = handleAndTranslateException(ex); - addFailureToHistory(time, PodHistoryEntryType.GetPodInfo, comment); - return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); - } - } - public PumpEnactResult suspendDelivery() { try { delegate.suspendDelivery(isBasalBeepsEnabled()); } catch (Exception ex) { String comment = handleAndTranslateException(ex); + addFailureToHistory(PodHistoryEntryType.SUSPEND_DELIVERY, comment); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); } + addSuccessToHistory(PodHistoryEntryType.SUSPEND_DELIVERY, null); + + createSuspendedFakeTbrIfNotExists(); + return new PumpEnactResult(injector).success(true).enacted(true); } - public PumpEnactResult resumeDelivery() { - try { - delegate.resumeDelivery(isBasalBeepsEnabled()); - } catch (Exception ex) { - String comment = handleAndTranslateException(ex); - return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); - } - - return new PumpEnactResult(injector).success(true).enacted(true); - } - - // TODO should we add this to the OmnipodCommunicationManager interface? // Updates the pods current time based on the device timezone and the pod's time zone public PumpEnactResult setTime() { - long time = System.currentTimeMillis(); try { delegate.setTime(isBasalBeepsEnabled()); - // Because set time actually suspends and then resumes delivery, TBR is implicitly cancelled - reportImplicitlyCanceledTbr(); - addSuccessToHistory(time, PodHistoryEntryType.SetTime, null); + addSuccessToHistory(PodHistoryEntryType.SET_TIME, null); + } catch (CommandFailedAfterChangingDeliveryStatusException ex) { + createSuspendedFakeTbrIfNotExists(); + String comment = getStringResource(R.string.omnipod_error_set_time_failed_delivery_suspended); + showNotification(comment, Notification.URGENT, R.raw.boluserror); + addFailureToHistory(PodHistoryEntryType.SET_TIME, comment); + return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); + } catch (DeliveryStatusVerificationFailedException ex) { + String comment = getStringResource(R.string.omnipod_error_set_time_failed_delivery_might_be_suspended); + showNotification(comment, Notification.URGENT, R.raw.boluserror); + addFailureToHistory(PodHistoryEntryType.SET_TIME, comment); + return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); } catch (Exception ex) { - if ((ex instanceof OmnipodException) && !((OmnipodException) ex).isCertainFailure()) { - reportImplicitlyCanceledTbr(); - addFailureToHistory(time, PodHistoryEntryType.SetTime, "Uncertain failure"); - return new PumpEnactResult(injector).success(false).enacted(false).comment(getStringResource(R.string.omnipod_error_set_time_failed_uncertain)); - } String comment = handleAndTranslateException(ex); - reportImplicitlyCanceledTbr(); - addFailureToHistory(time, PodHistoryEntryType.SetTime, comment); + addFailureToHistory(PodHistoryEntryType.SET_TIME, comment); return new PumpEnactResult(injector).success(false).enacted(false).comment(comment); } @@ -490,10 +529,10 @@ public class AapsOmnipodManager implements IOmnipodManager { public PodInfoRecentPulseLog readPulseLog() { PodInfoResponse response = delegate.getPodInfo(PodInfoType.RECENT_PULSE_LOG); - return response.getPodInfo(); + return (PodInfoRecentPulseLog) response.getPodInfo(); } - public OmnipodCommunicationManager getCommunicationService() { + public OmnipodRileyLinkCommunicationManager getCommunicationService() { return delegate.getCommunicationService(); } @@ -501,40 +540,118 @@ public class AapsOmnipodManager implements IOmnipodManager { return delegate.getTime(); } - public boolean isInitialized() { - return delegate.isPodRunning(); + public boolean isBasalBeepsEnabled() { + return basalBeepsEnabled; + } + + public boolean isBolusBeepsEnabled() { + return bolusBeepsEnabled; + } + + public boolean isSmbBeepsEnabled() { + return smbBeepsEnabled; + } + + public boolean isTbrBeepsEnabled() { + return tbrBeepsEnabled; + } + + public boolean isSuspendDeliveryButtonEnabled() { + return suspendDeliveryButtonEnabled; + } + + public boolean isPulseLogButtonEnabled() { + return pulseLogButtonEnabled; + } + + public boolean isTimeChangeEventEnabled() { + return timeChangeEventEnabled; } public void addBolusToHistory(DetailedBolusInfo detailedBolusInfo) { - long pumpId = addSuccessToHistory(detailedBolusInfo.date, PodHistoryEntryType.SetBolus, detailedBolusInfo.insulin + ";" + detailedBolusInfo.carbs); + long pumpId = addSuccessToHistory(detailedBolusInfo.date, PodHistoryEntryType.SET_BOLUS, detailedBolusInfo.insulin + ";" + detailedBolusInfo.carbs); detailedBolusInfo.pumpId = pumpId; activePlugin.getActiveTreatments().addToHistoryTreatment(detailedBolusInfo, false); } - private void reportImplicitlyCanceledTbr() { - //TreatmentsPlugin plugin = TreatmentsPlugin.getPlugin(); - TreatmentsInterface plugin = activePlugin.getActiveTreatments(); - if (plugin.isTempBasalInProgress()) { - aapsLogger.debug(LTag.PUMP, "Reporting implicitly cancelled TBR to Treatments plugin"); + public synchronized void createSuspendedFakeTbrIfNotExists() { + if (!hasSuspendedFakeTbr()) { + aapsLogger.debug(LTag.PUMP, "Creating fake suspended TBR"); - long time = System.currentTimeMillis() - 1000; - - addSuccessToHistory(time, PodHistoryEntryType.CancelTemporaryBasal, null); + long pumpId = addSuccessToHistory(System.currentTimeMillis(), PodHistoryEntryType.SET_FAKE_SUSPENDED_TEMPORARY_BASAL, null); TemporaryBasal temporaryBasal = new TemporaryBasal(injector) // - .date(time) // - .duration(0) // - .pumpId(pumpStatus.tempBasalPumpId) - .source(Source.PUMP); + .date(System.currentTimeMillis()) // + .absolute(0.0) // + .duration((int) OmnipodConstants.SERVICE_DURATION.getStandardMinutes()) // + .source(Source.PUMP) // + .pumpId(pumpId); - plugin.addToHistoryTempBasal(temporaryBasal); + activePlugin.getActiveTreatments().addToHistoryTempBasal(temporaryBasal); } } + public synchronized void cancelSuspendedFakeTbrIfExists() { + if (hasSuspendedFakeTbr()) { + aapsLogger.debug(LTag.PUMP, "Cancelling fake suspended TBR"); + long pumpId = addSuccessToHistory(System.currentTimeMillis(), PodHistoryEntryType.CANCEL_FAKE_SUSPENDED_TEMPORARY_BASAL, null); + + TemporaryBasal temporaryBasal = new TemporaryBasal(injector) // + .date(System.currentTimeMillis()) // + .duration(0) // + .source(Source.PUMP) // + .pumpId(pumpId); + + activePlugin.getActiveTreatments().addToHistoryTempBasal(temporaryBasal); + } + } + + public boolean hasSuspendedFakeTbr() { + if (activePlugin.getActiveTreatments().isTempBasalInProgress()) { + TemporaryBasal tempBasal = activePlugin.getActiveTreatments().getTempBasalFromHistory(System.currentTimeMillis()); + OmnipodHistoryRecord historyRecord = databaseHelper.findOmnipodHistoryRecordByPumpId(tempBasal.pumpId); + return historyRecord != null && PodHistoryEntryType.getByCode(historyRecord.getPodEntryTypeCode()).equals(PodHistoryEntryType.SET_FAKE_SUSPENDED_TEMPORARY_BASAL); + } + return false; + } + + public void reportCancelledTbr() { + aapsLogger.debug(LTag.PUMP, "Reporting cancelled TBR to AAPS"); + + long pumpId = addSuccessToHistory(PodHistoryEntryType.CANCEL_TEMPORARY_BASAL_BY_DRIVER, null); + + TemporaryBasal temporaryBasal = new TemporaryBasal(injector) // + .date(System.currentTimeMillis()) // + .duration(0) // + .source(Source.PUMP) // + .pumpId(pumpId); + + activePlugin.getActiveTreatments().addToHistoryTempBasal(temporaryBasal); + } + + private void addTempBasalTreatment(long time, long pumpId, TempBasalPair tempBasalPair) { + TemporaryBasal tempStart = new TemporaryBasal(injector) // + .date(time) // + .duration(tempBasalPair.getDurationMinutes()) // + .absolute(tempBasalPair.getInsulinRate()) // + .pumpId(pumpId) + .source(Source.PUMP); + + activePlugin.getActiveTreatments().addToHistoryTempBasal(tempStart); + } + + private long addSuccessToHistory(PodHistoryEntryType entryType, Object data) { + return addSuccessToHistory(System.currentTimeMillis(), entryType, data); + } + private long addSuccessToHistory(long requestTime, PodHistoryEntryType entryType, Object data) { return addToHistory(requestTime, entryType, data, true); } + private long addFailureToHistory(PodHistoryEntryType entryType, Object data) { + return addFailureToHistory(System.currentTimeMillis(), entryType, data); + } + private long addFailureToHistory(long requestTime, PodHistoryEntryType entryType, Object data) { return addToHistory(requestTime, entryType, data, false); } @@ -546,7 +663,7 @@ public class AapsOmnipodManager implements IOmnipodManager { if (data instanceof String) { omnipodHistoryRecord.setData((String) data); } else { - omnipodHistoryRecord.setData(omnipodUtil.getGsonInstance().toJson(data)); + omnipodHistoryRecord.setData(aapsOmnipodUtil.getGsonInstance().toJson(data)); } } @@ -573,10 +690,10 @@ public class AapsOmnipodManager implements IOmnipodManager { break; } - if (podInitActionType == PodInitActionType.PairAndPrimeWizardStep) { - addToHistory(time, PodHistoryEntryType.PairAndPrime, comment, res.getResultType().isSuccess()); + if (podInitActionType == PodInitActionType.PAIR_AND_PRIME_WIZARD_STEP) { + addToHistory(time, PodHistoryEntryType.PAIR_AND_PRIME, comment, res.getResultType().isSuccess()); } else { - addToHistory(time, PodHistoryEntryType.FillCannulaSetBasalProfile, res.getResultType().isSuccess() ? profile.getBasalValues() : comment, res.getResultType().isSuccess()); + addToHistory(time, PodHistoryEntryType.FILL_CANNULA_SET_BASAL_PROFILE, res.getResultType().isSuccess() ? profile.getBasalValues() : comment, res.getResultType().isSuccess()); } podInitReceiver.returnInitTaskStatus(podInitActionType, res.getResultType().isSuccess(), comment); @@ -618,7 +735,7 @@ public class AapsOmnipodManager implements IOmnipodManager { comment = getStringResource(R.string.omnipod_driver_error_not_enough_data); } else if (ex instanceof PodFaultException) { FaultEventCode faultEventCode = ((PodFaultException) ex).getFaultEvent().getFaultEventCode(); - showPodFaultErrorDialog(faultEventCode); + showPodFaultNotification(faultEventCode); comment = createPodFaultErrorMessage(faultEventCode); } else if (ex instanceof PodReturnedErrorResponseException) { comment = getStringResource(R.string.omnipod_driver_error_pod_returned_error_response); @@ -646,30 +763,21 @@ public class AapsOmnipodManager implements IOmnipodManager { rxBus.send(event); } - private void showPodFaultErrorDialog(FaultEventCode faultEventCode) { - showErrorDialog(createPodFaultErrorMessage(faultEventCode), null); + private void showPodFaultNotification(FaultEventCode faultEventCode) { + showPodFaultNotification(faultEventCode, R.raw.boluserror); } - private void showPodFaultErrorDialog(FaultEventCode faultEventCode, Integer sound) { - showErrorDialog(createPodFaultErrorMessage(faultEventCode), sound); - } - - private void showErrorDialog(String message) { - showErrorDialog(message, null); - } - - 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, Integer sound) { + showNotification(createPodFaultErrorMessage(faultEventCode), Notification.URGENT, sound); } private void showNotification(String message, int urgency, Integer sound) { + showNotification(Notification.OMNIPOD_PUMP_ALARM, message, urgency, sound); + } + + private void showNotification(int id, String message, int urgency, Integer sound) { Notification notification = new Notification( // - Notification.OMNIPOD_PUMP_ALARM, // + id, // message, // urgency); if (sound != null) { @@ -678,27 +786,11 @@ public class AapsOmnipodManager implements IOmnipodManager { sendEvent(new EventNewNotification(notification)); } - private boolean isBolusBeepsEnabled() { - return this.pumpStatus.beepBolusEnabled; - } - - private boolean isSmbBeepsEnabled() { - return this.pumpStatus.beepSMBEnabled; - } - - private boolean isBasalBeepsEnabled() { - return this.pumpStatus.beepBasalEnabled; - } - - private boolean isTempBasalBeepsEnabled() { - return this.pumpStatus.beepTBREnabled; - } - private String getStringResource(int id, Object... args) { return resourceHelper.gs(id, args); } - static BasalSchedule mapProfileToBasalSchedule(Profile profile) { + public static BasalSchedule mapProfileToBasalSchedule(Profile profile) { if (profile == null) { throw new IllegalArgumentException("Profile can not be null"); } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/manager/AapsPodStateManager.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/manager/AapsPodStateManager.java new file mode 100644 index 0000000000..158c4472ad --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/manager/AapsPodStateManager.java @@ -0,0 +1,38 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.manager; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import info.nightscout.androidaps.logging.AAPSLogger; +import info.nightscout.androidaps.plugins.bus.RxBusWrapper; +import info.nightscout.androidaps.plugins.pump.omnipod.definition.OmnipodStorageKeys; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodTbrChanged; +import info.nightscout.androidaps.utils.sharedPreferences.SP; + +@Singleton +public class AapsPodStateManager extends PodStateManager { + private final SP sp; + private final RxBusWrapper rxBus; + + @Inject + public AapsPodStateManager(AAPSLogger aapsLogger, SP sp, RxBusWrapper rxBus) { + super(aapsLogger); + this.sp = sp; + this.rxBus = rxBus; + } + + @Override + protected String readPodState() { + return sp.getString(OmnipodStorageKeys.Preferences.POD_STATE, ""); + } + + @Override + protected void storePodState(String podState) { + sp.putString(OmnipodStorageKeys.Preferences.POD_STATE, podState); + } + + @Override protected void onTbrChanged() { + rxBus.send(new EventOmnipodTbrChanged()); + } +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodCommunicationManager.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/rileylink/manager/OmnipodRileyLinkCommunicationManager.java similarity index 64% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodCommunicationManager.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/rileylink/manager/OmnipodRileyLinkCommunicationManager.java index e0232e7d87..19b6b6a4a0 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/comm/OmnipodCommunicationManager.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/rileylink/manager/OmnipodRileyLinkCommunicationManager.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.comm; +package info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager; import org.joda.time.DateTime; @@ -9,67 +9,50 @@ import javax.inject.Inject; import javax.inject.Singleton; import info.nightscout.androidaps.logging.LTag; -import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus; import info.nightscout.androidaps.plugins.pump.common.defs.PumpDeviceState; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkCommunicationManager; -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RileyLinkCommunicationException; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.RLMessage; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RLMessageType; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkBLEError; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.OmnipodAction; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.CommunicationException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalMessageAddressException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalMessageSequenceNumberException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalPacketTypeException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalResponseException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.NonceOutOfSyncException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.NonceResyncException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.NotEnoughDataException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.PodFaultException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.PodReturnedErrorResponseException; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.MessageBlock; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.OmnipodMessage; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.OmnipodPacket; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.DeactivatePodCommand; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.ErrorResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoFaultEvent; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.MessageBlockType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PacketType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.OmnipodAction; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.MessageBlock; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.OmnipodMessage; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.OmnipodPacket; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.DeactivatePodCommand; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.ErrorResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusUpdatableResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfo; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoFaultEvent; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.MessageBlockType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PacketType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.CommunicationException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalMessageAddressException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalMessageSequenceNumberException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPacketTypeException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalResponseException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.NonceOutOfSyncException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.NonceResyncException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.NotEnoughDataException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.OmnipodException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.PodFaultException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.PodReturnedErrorResponseException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; /** * Created by andy on 6/29/18. */ -// TODO rename to OmnipodRileyLinkCommunicationManager @Singleton -public class OmnipodCommunicationManager extends RileyLinkCommunicationManager { - - @Inject OmnipodPumpStatus omnipodPumpStatus; - +public class OmnipodRileyLinkCommunicationManager extends RileyLinkCommunicationManager { // This empty constructor must be kept, otherwise dagger injection might break! @Inject - public OmnipodCommunicationManager() { + public OmnipodRileyLinkCommunicationManager() { } - @Inject - public void onInit() { - // this cannot be done in the constructor, as sp is not populated at that time - omnipodPumpStatus.previousConnection = sp.getLong( - RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L); - } - -// @Override -// protected void configurePumpSpecificSettings() { -// } - @Override public boolean tryToConnectToDevice() { // TODO @@ -92,7 +75,8 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager { @Override public void setPumpDeviceState(PumpDeviceState pumpDeviceState) { - this.omnipodPumpStatus.setPumpDeviceState(pumpDeviceState); + // Intentionally left blank + // We don't use PumpDeviceState in the Omnipod driver } public T sendCommand(Class responseClass, PodStateManager podStateManager, MessageBlock command) { @@ -122,64 +106,73 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager { } public synchronized T exchangeMessages(Class responseClass, PodStateManager podStateManager, OmnipodMessage message, Integer addressOverride, Integer ackAddressOverride, boolean automaticallyResyncNonce) { - - aapsLogger.debug(LTag.PUMPCOMM, "Exchanging OmnipodMessage [responseClass={}, podStateManager={}, message={}, addressOverride={}, ackAddressOverride={}, automaticallyResyncNonce={}]: {}", // + aapsLogger.debug(LTag.PUMPBTCOMM, "Exchanging OmnipodMessage: responseClass={}, podStateManager={}, message={}, addressOverride={}, ackAddressOverride={}, automaticallyResyncNonce={}", // responseClass.getSimpleName(), podStateManager, message, addressOverride, ackAddressOverride, automaticallyResyncNonce); - for (int i = 0; 2 > i; i++) { + try { + for (int i = 0; 2 > i; i++) { - if (podStateManager.isPodInitialized() && message.isNonceResyncable()) { - podStateManager.advanceToNextNonce(); - } + if (podStateManager.isPodInitialized() && message.isNonceResyncable()) { + podStateManager.advanceToNextNonce(); + } - MessageBlock responseMessageBlock; - try { - responseMessageBlock = transportMessages(podStateManager, message, addressOverride, ackAddressOverride); - } catch (Exception ex) { - podStateManager.setLastFailedCommunication(DateTime.now()); - throw ex; - } + MessageBlock responseMessageBlock; + try { + responseMessageBlock = transportMessages(podStateManager, message, addressOverride, ackAddressOverride); + } catch (Exception ex) { + podStateManager.setLastFailedCommunication(DateTime.now()); + throw ex; + } - aapsLogger.debug(LTag.PUMPCOMM, "Received response from the Pod [responseMessageBlock={}]", responseMessageBlock); + aapsLogger.debug(LTag.PUMPBTCOMM, "Received response from the Pod [responseMessageBlock={}]", responseMessageBlock); - if (responseMessageBlock instanceof StatusResponse) { - podStateManager.updateFromStatusResponse((StatusResponse) responseMessageBlock); - } + if (responseMessageBlock instanceof StatusUpdatableResponse) { + podStateManager.updateFromResponse((StatusUpdatableResponse) responseMessageBlock); + } else if (responseMessageBlock instanceof PodInfoResponse) { + PodInfo podInfo = ((PodInfoResponse) responseMessageBlock).getPodInfo(); + if (podInfo instanceof StatusUpdatableResponse) { + podStateManager.updateFromResponse((StatusUpdatableResponse) podInfo); + } + } - if (responseClass.isInstance(responseMessageBlock)) { - podStateManager.setLastSuccessfulCommunication(DateTime.now()); - return (T) responseMessageBlock; - } else { - if (responseMessageBlock.getType() == MessageBlockType.ERROR_RESPONSE) { - ErrorResponse error = (ErrorResponse) responseMessageBlock; - if (error.getErrorResponseCode() == ErrorResponse.ERROR_RESPONSE_CODE_BAD_NONCE) { - podStateManager.resyncNonce(error.getNonceSearchKey(), message.getSentNonce(), message.getSequenceNumber()); - if (automaticallyResyncNonce) { - aapsLogger.warn(LTag.PUMPCOMM, "Received ErrorResponse 0x14 (Nonce out of sync). Resyncing nonce and retrying to send message as automaticallyResyncNonce=true"); - message.resyncNonce(podStateManager.getCurrentNonce()); + if (responseClass.isInstance(responseMessageBlock)) { + podStateManager.setLastSuccessfulCommunication(DateTime.now()); + return (T) responseMessageBlock; + } else { + if (responseMessageBlock.getType() == MessageBlockType.ERROR_RESPONSE) { + ErrorResponse error = (ErrorResponse) responseMessageBlock; + if (error.getErrorResponseCode() == ErrorResponse.ERROR_RESPONSE_CODE_BAD_NONCE) { + podStateManager.resyncNonce(error.getNonceSearchKey(), message.getSentNonce(), message.getSequenceNumber()); + if (automaticallyResyncNonce) { + aapsLogger.warn(LTag.PUMPBTCOMM, "Received ErrorResponse 0x14 (Nonce out of sync). Resyncing nonce and retrying to send message as automaticallyResyncNonce=true"); + message.resyncNonce(podStateManager.getCurrentNonce()); + } else { + aapsLogger.warn(LTag.PUMPBTCOMM, "Received ErrorResponse 0x14 (Nonce out of sync). Not resyncing nonce as automaticallyResyncNonce=true"); + podStateManager.setLastFailedCommunication(DateTime.now()); + throw new NonceOutOfSyncException(); + } } else { - aapsLogger.warn(LTag.PUMPCOMM, "Received ErrorResponse 0x14 (Nonce out of sync). Not resyncing nonce as automaticallyResyncNonce=true"); podStateManager.setLastFailedCommunication(DateTime.now()); - throw new NonceOutOfSyncException(); + throw new PodReturnedErrorResponseException(error); } + } else if (responseMessageBlock.getType() == MessageBlockType.POD_INFO_RESPONSE && ((PodInfoResponse) responseMessageBlock).getSubType() == PodInfoType.FAULT_EVENT) { + PodInfoFaultEvent faultEvent = (PodInfoFaultEvent) ((PodInfoResponse) responseMessageBlock).getPodInfo(); + podStateManager.setFaultEvent(faultEvent); + // Treat as successful communication as the user will get notified and can work with this response + podStateManager.setLastSuccessfulCommunication(DateTime.now()); + throw new PodFaultException(faultEvent); } else { podStateManager.setLastFailedCommunication(DateTime.now()); - throw new PodReturnedErrorResponseException(error); + throw new IllegalResponseException(responseClass.getSimpleName(), responseMessageBlock.getType()); } - } else if (responseMessageBlock.getType() == MessageBlockType.POD_INFO_RESPONSE && ((PodInfoResponse) responseMessageBlock).getSubType() == PodInfoType.FAULT_EVENT) { - PodInfoFaultEvent faultEvent = ((PodInfoResponse) responseMessageBlock).getPodInfo(); - podStateManager.setFaultEvent(faultEvent); - podStateManager.setLastFailedCommunication(DateTime.now()); - throw new PodFaultException(faultEvent); - } else { - podStateManager.setLastFailedCommunication(DateTime.now()); - throw new IllegalResponseException(responseClass.getSimpleName(), responseMessageBlock.getType()); } } - } - podStateManager.setLastFailedCommunication(DateTime.now()); - throw new NonceResyncException(); + podStateManager.setLastFailedCommunication(DateTime.now()); + throw new NonceResyncException(); + } finally { + podStateManager.storePodState(); + } } private MessageBlock transportMessages(PodStateManager podStateManager, OmnipodMessage message, Integer addressOverride, Integer ackAddressOverride) { @@ -189,7 +182,7 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager { } if (podStateManager.getMessageNumber() != message.getSequenceNumber()) { - aapsLogger.warn(LTag.PUMPCOMM, "Message number in Pod State [{}] does not match message sequence number [{}]. Setting message number in Pod State to {}", podStateManager.getMessageNumber(), message.getSequenceNumber(), message.getSequenceNumber()); + aapsLogger.warn(LTag.PUMPBTCOMM, "Message number in Pod State [{}] does not match message sequence number [{}]. Setting message number in Pod State to {}", podStateManager.getMessageNumber(), message.getSequenceNumber(), message.getSequenceNumber()); podStateManager.setMessageNumber(message.getSequenceNumber()); } @@ -240,7 +233,7 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager { // so it's impossible for the pod to have received the message newException.setCertainFailure(!lastPacket); - aapsLogger.debug(LTag.PUMPCOMM, "Caught exception in transportMessages. Set certainFailure to {} because encodedMessage.length={}", newException.isCertainFailure(), encodedMessage.length); + aapsLogger.debug(LTag.PUMPBTCOMM, "Caught exception in transportMessages. Set certainFailure to {} because encodedMessage.length={}", newException.isCertainFailure(), encodedMessage.length); throw newException; } @@ -345,7 +338,7 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager { podStateManager.increasePacketNumber(); while (System.currentTimeMillis() < timeoutTime) { - OmnipodPacket response = null; + OmnipodPacket response; try { response = (OmnipodPacket) sendAndListen(packet, responseTimeoutMilliseconds, repeatCount, 9, preambleExtensionMilliseconds); } catch (RileyLinkCommunicationException | OmnipodException ex) { @@ -363,7 +356,7 @@ public class OmnipodCommunicationManager extends RileyLinkCommunicationManager { continue; } if (response.getAddress() != packet.getAddress() && - response.getAddress() != OmnipodConst.DEFAULT_ADDRESS) { // In some (strange) cases, the Pod remains a packet address of 0xffffffff during it's lifetime + response.getAddress() != OmnipodConstants.DEFAULT_ADDRESS) { // In some (strange) cases, the Pod remains a packet address of 0xffffffff during it's lifetime aapsLogger.debug(LTag.PUMPBTCOMM, "Packet address " + response.getAddress() + " doesn't match " + packet.getAddress()); continue; } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/rileylink/service/RileyLinkOmnipodService.java similarity index 50% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/rileylink/service/RileyLinkOmnipodService.java index 90612bc815..8928e5b1f1 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/service/RileyLinkOmnipodService.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/rileylink/service/RileyLinkOmnipodService.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.service; +package info.nightscout.androidaps.plugins.pump.omnipod.rileylink.service; import android.content.Intent; import android.content.res.Configuration; @@ -20,15 +20,10 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLin import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkService; import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodPumpPlugin; import info.nightscout.androidaps.plugins.pump.omnipod.R; -import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationManager; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.OmnipodPumpStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.comm.AapsOmnipodManager; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.ui.OmnipodUIComm; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.ui.OmnipodUIPostprocessor; -import info.nightscout.androidaps.plugins.pump.omnipod.events.EventOmnipodPumpValuesChanged; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodConst; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.manager.AapsOmnipodManager; +import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; +import info.nightscout.androidaps.plugins.pump.omnipod.util.AapsOmnipodUtil; /** @@ -37,20 +32,20 @@ import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil; */ public class RileyLinkOmnipodService extends RileyLinkService { + private static final String REGEX_MAC = "([\\da-fA-F]{1,2}(?:\\:|$)){6}"; + @Inject OmnipodPumpPlugin omnipodPumpPlugin; - @Inject OmnipodPumpStatus omnipodPumpStatus; - @Inject OmnipodUtil omnipodUtil; - @Inject OmnipodUIPostprocessor omnipodUIPostprocessor; + @Inject AapsOmnipodUtil aapsOmnipodUtil; @Inject PodStateManager podStateManager; @Inject DatabaseHelperInterface databaseHelper; @Inject AapsOmnipodManager aapsOmnipodManager; - @Inject OmnipodCommunicationManager omnipodCommunicationManager; + @Inject OmnipodRileyLinkCommunicationManager omnipodRileyLinkCommunicationManager; - private IBinder mBinder = new LocalBinder(); + private final IBinder mBinder = new LocalBinder(); private boolean rileyLinkAddressChanged = false; private boolean inPreInit = true; - - OmnipodUIComm omnipodUIComm; + private String rileyLinkAddress; + private String errorDescription; public RileyLinkOmnipodService() { super(); @@ -58,7 +53,7 @@ public class RileyLinkOmnipodService extends RileyLinkService { @Override public void onConfigurationChanged(Configuration newConfig) { - aapsLogger.warn(LTag.PUMPCOMM, "onConfigurationChanged"); + aapsLogger.warn(LTag.PUMPBTCOMM, "onConfigurationChanged"); super.onConfigurationChanged(newConfig); } @@ -72,45 +67,31 @@ public class RileyLinkOmnipodService extends RileyLinkService { return RileyLinkEncodingType.Manchester; } - /** - * If you have customized RileyLinkServiceData you need to override this - */ @Override public void initRileyLinkServiceData() { - rileyLinkServiceData.targetDevice = RileyLinkTargetDevice.Omnipod; rileyLinkServiceData.rileyLinkTargetFrequency = RileyLinkTargetFrequency.Omnipod; - // get most recently used RileyLink address rileyLinkServiceData.rileylinkAddress = sp.getString(RileyLinkConst.Prefs.RileyLinkAddress, ""); rfspy.startReader(); - initializeErosOmnipodManager(); - - aapsLogger.debug(LTag.PUMPCOMM, "RileyLinkOmnipodService newly constructed"); - //omnipodPumpStatus = (OmnipodPumpStatus) omnipodPumpPlugin.getPumpStatusData(); - } - - private void initializeErosOmnipodManager() { - if (omnipodUIComm == null) { - omnipodUIComm = new OmnipodUIComm(injector, aapsLogger, omnipodUIPostprocessor, aapsOmnipodManager, rileyLinkUtil); - } - rxBus.send(new EventOmnipodPumpValuesChanged()); - } - - public OmnipodUIComm getDeviceCommandExecutor() { - return this.omnipodUIComm; + aapsLogger.debug(LTag.PUMPBTCOMM, "RileyLinkOmnipodService newly constructed"); } @Override public RileyLinkCommunicationManager getDeviceCommunicationManager() { - return omnipodCommunicationManager; + return omnipodRileyLinkCommunicationManager; } @Override public void setPumpDeviceState(PumpDeviceState pumpDeviceState) { - this.omnipodPumpStatus.setPumpDeviceState(pumpDeviceState); + // Intentionally left blank + // We don't use PumpDeviceState in the Omnipod driver + } + + public String getErrorDescription() { + return errorDescription; } public class LocalBinder extends Binder { @@ -130,43 +111,35 @@ public class RileyLinkOmnipodService extends RileyLinkService { @Override public boolean verifyConfiguration() { try { - omnipodPumpStatus.rileyLinkErrorDescription = null; + errorDescription = null; String rileyLinkAddress = sp.getString(RileyLinkConst.Prefs.RileyLinkAddress, ""); if (StringUtils.isEmpty(rileyLinkAddress)) { - aapsLogger.debug(LTag.PUMPCOMM, "RileyLink address invalid: no address"); - omnipodPumpStatus.rileyLinkErrorDescription = resourceHelper.gs(R.string.omnipod_error_rileylink_address_invalid); + aapsLogger.debug(LTag.PUMPBTCOMM, "RileyLink address invalid: no address"); + errorDescription = resourceHelper.gs(R.string.omnipod_error_rileylink_address_invalid); return false; } else { - if (!rileyLinkAddress.matches(omnipodPumpStatus.regexMac)) { - omnipodPumpStatus.rileyLinkErrorDescription = resourceHelper.gs(R.string.omnipod_error_rileylink_address_invalid); - aapsLogger.debug(LTag.PUMPCOMM, "RileyLink address invalid: {}", rileyLinkAddress); + if (!rileyLinkAddress.matches(REGEX_MAC)) { + errorDescription = resourceHelper.gs(R.string.omnipod_error_rileylink_address_invalid); + aapsLogger.debug(LTag.PUMPBTCOMM, "RileyLink address invalid: {}", rileyLinkAddress); } else { - if (!rileyLinkAddress.equals(this.omnipodPumpStatus.rileyLinkAddress)) { - this.omnipodPumpStatus.rileyLinkAddress = rileyLinkAddress; + if (!rileyLinkAddress.equals(this.rileyLinkAddress)) { + this.rileyLinkAddress = rileyLinkAddress; rileyLinkAddressChanged = true; } } } - this.omnipodPumpStatus.beepBasalEnabled = sp.getBoolean(OmnipodConst.Prefs.BeepBasalEnabled, true); - this.omnipodPumpStatus.beepBolusEnabled = sp.getBoolean(OmnipodConst.Prefs.BeepBolusEnabled, true); - this.omnipodPumpStatus.beepSMBEnabled = sp.getBoolean(OmnipodConst.Prefs.BeepSMBEnabled, true); - this.omnipodPumpStatus.beepTBREnabled = sp.getBoolean(OmnipodConst.Prefs.BeepTBREnabled, true); - this.omnipodPumpStatus.podDebuggingOptionsEnabled = sp.getBoolean(OmnipodConst.Prefs.PodDebuggingOptionsEnabled, false); - this.omnipodPumpStatus.timeChangeEventEnabled = sp.getBoolean(OmnipodConst.Prefs.TimeChangeEventEnabled, true); rileyLinkServiceData.rileyLinkTargetFrequency = RileyLinkTargetFrequency.Omnipod; - aapsLogger.debug(LTag.PUMPCOMM, "Beeps [basal={}, bolus={}, SMB={}, TBR={}]", this.omnipodPumpStatus.beepBasalEnabled, this.omnipodPumpStatus.beepBolusEnabled, this.omnipodPumpStatus.beepSMBEnabled, this.omnipodPumpStatus.beepTBREnabled); - reconfigureService(); return true; } catch (Exception ex) { - this.omnipodPumpStatus.rileyLinkErrorDescription = ex.getMessage(); - aapsLogger.error(LTag.PUMPCOMM, "Error on Verification: " + ex.getMessage(), ex); + errorDescription = ex.getMessage(); + aapsLogger.error(LTag.PUMPBTCOMM, "Error on Verification: " + ex.getMessage(), ex); return false; } } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/OmnipodFragment.kt b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/OmnipodFragment.kt new file mode 100644 index 0000000000..4aec08bb70 --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/OmnipodFragment.kt @@ -0,0 +1,523 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.ui + +import android.content.Intent +import android.graphics.Color +import android.os.Bundle +import android.os.Handler +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import dagger.android.support.DaggerFragment +import info.nightscout.androidaps.Constants +import info.nightscout.androidaps.events.EventPreferenceChange +import info.nightscout.androidaps.interfaces.ActivePluginProvider +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.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 +import info.nightscout.androidaps.plugins.pump.omnipod.definition.OmnipodStatusRequestType +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager +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.util.AapsOmnipodUtil +import info.nightscout.androidaps.queue.commands.Command +import info.nightscout.androidaps.queue.events.EventQueueChanged +import info.nightscout.androidaps.utils.DateUtil +import info.nightscout.androidaps.utils.FabricPrivacy +import info.nightscout.androidaps.utils.WarnColors +import info.nightscout.androidaps.utils.alertDialogs.OKDialog +import info.nightscout.androidaps.utils.extensions.plusAssign +import info.nightscout.androidaps.utils.protection.ProtectionCheck +import info.nightscout.androidaps.utils.resources.ResourceHelper +import info.nightscout.androidaps.utils.sharedPreferences.SP +import info.nightscout.androidaps.utils.ui.UIRunnable +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.schedulers.Schedulers +import kotlinx.android.synthetic.main.omnipod_fragment.* +import org.apache.commons.lang3.StringUtils +import org.joda.time.DateTime +import org.joda.time.Duration +import javax.inject.Inject + +class OmnipodFragment : DaggerFragment() { + companion object { + private val REFRESH_INTERVAL_MILLIS = 15 * 1000L; // 15 seconds + private val PLACEHOLDER = "-"; // 15 seconds + } + + @Inject lateinit var fabricPrivacy: FabricPrivacy + @Inject lateinit var resourceHelper: ResourceHelper + @Inject lateinit var rxBus: RxBusWrapper + @Inject lateinit var commandQueue: CommandQueueProvider + @Inject lateinit var activePlugin: ActivePluginProvider + @Inject lateinit var omnipodPumpPlugin: OmnipodPumpPlugin + @Inject lateinit var warnColors: WarnColors + @Inject lateinit var podStateManager: PodStateManager + @Inject lateinit var sp: SP + @Inject lateinit var omnipodUtil: AapsOmnipodUtil + @Inject lateinit var rileyLinkServiceData: RileyLinkServiceData + @Inject lateinit var dateUtil: DateUtil + @Inject lateinit var omnipodManager: AapsOmnipodManager + @Inject lateinit var protectionCheck: ProtectionCheck + + private var disposables: CompositeDisposable = CompositeDisposable() + + private val loopHandler = Handler() + private lateinit var refreshLoop: Runnable + + init { + refreshLoop = Runnable { + activity?.runOnUiThread { updateUi() } + loopHandler.postDelayed(refreshLoop, REFRESH_INTERVAL_MILLIS) + } + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return inflater.inflate(R.layout.omnipod_fragment, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + omnipod_button_resume_delivery.setOnClickListener { + disablePodActionButtons() + commandQueue.startPump(null) + } + + omnipod_button_pod_mgmt.setOnClickListener { + if (omnipodPumpPlugin.rileyLinkService?.verifyConfiguration() == true) { + activity?.let { activity -> + protectionCheck.queryProtection( + activity, ProtectionCheck.Protection.PREFERENCES, + UIRunnable(Runnable { startActivity(Intent(context, PodManagementActivity::class.java)) }) + ) + } + } else { + displayNotConfiguredDialog() + } + } + + omnipod_button_refresh_status.setOnClickListener { + disablePodActionButtons() + omnipodPumpPlugin.addPodStatusRequest(OmnipodStatusRequestType.GET_POD_STATE); + commandQueue.readStatus("Clicked Refresh", null) + } + + omnipod_button_rileylink_stats.setOnClickListener { + if (omnipodPumpPlugin.rileyLinkService?.verifyConfiguration() == true) { + startActivity(Intent(context, RileyLinkStatusActivity::class.java)) + } else { + displayNotConfiguredDialog() + } + } + + omnipod_button_acknowledge_active_alerts.setOnClickListener { + disablePodActionButtons() + omnipodPumpPlugin.addPodStatusRequest(OmnipodStatusRequestType.ACKNOWLEDGE_ALERTS); + commandQueue.readStatus("Clicked Acknowledge Alert", null) + } + + omnipod_button_suspend_delivery.setOnClickListener { + disablePodActionButtons() + omnipodPumpPlugin.addPodStatusRequest(OmnipodStatusRequestType.SUSPEND_DELIVERY); + commandQueue.readStatus("Clicked Suspend Delivery", null) + } + + omnipod_button_pulse_log.setOnClickListener { + disablePodActionButtons() + omnipodPumpPlugin.addPodStatusRequest(OmnipodStatusRequestType.GET_PULSE_LOG); + commandQueue.readStatus("Clicked Pulse Log", null) + } + } + + override fun onResume() { + super.onResume() + loopHandler.postDelayed(refreshLoop, REFRESH_INTERVAL_MILLIS) + disposables += rxBus + .toObservable(EventRileyLinkDeviceStatusChange::class.java) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ + updateRileyLinkStatus() + updatePodActionButtons() + }, { fabricPrivacy.logException(it) }) + disposables += rxBus + .toObservable(EventOmnipodPumpValuesChanged::class.java) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ + updateOmnipodStatus() + updatePodActionButtons() + }, { fabricPrivacy.logException(it) }) + disposables += rxBus + .toObservable(EventQueueChanged::class.java) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ + updateQueueStatus() + updatePodActionButtons() + }, { fabricPrivacy.logException(it) }) + disposables += rxBus + .toObservable(EventPreferenceChange::class.java) + .observeOn(Schedulers.io()) + .subscribe({ + updatePulseLogButton() + }, { fabricPrivacy.logException(it) }) + updateUi() + } + + override fun onPause() { + super.onPause() + disposables.clear() + loopHandler.removeCallbacks(refreshLoop) + } + + private fun updateUi() { + updateRileyLinkStatus() + updateOmnipodStatus() + updatePodActionButtons() + updateQueueStatus() + } + + @Synchronized + private fun updateRileyLinkStatus() { + val rileyLinkServiceState = rileyLinkServiceData.rileyLinkServiceState + + val resourceId = rileyLinkServiceState.getResourceId() + val rileyLinkError = rileyLinkServiceData.rileyLinkError + + omnipod_rl_status.text = + when { + rileyLinkServiceState == RileyLinkServiceState.NotStarted -> resourceHelper.gs(resourceId) + rileyLinkServiceState.isConnecting -> "{fa-bluetooth-b spin} " + resourceHelper.gs(resourceId) + rileyLinkServiceState.isError && rileyLinkError == null -> "{fa-bluetooth-b} " + resourceHelper.gs(resourceId) + rileyLinkServiceState.isError && rileyLinkError != null -> "{fa-bluetooth-b} " + resourceHelper.gs(rileyLinkError.getResourceId(RileyLinkTargetDevice.Omnipod)) + else -> "{fa-bluetooth-b} " + resourceHelper.gs(resourceId) + } + omnipod_rl_status.setTextColor(if (rileyLinkServiceState.isError || rileyLinkError != null) Color.RED else Color.WHITE) + } + + private fun updateOmnipodStatus() { + updateLastConnection() + updateLastBolus() + updateTempBasal() + updatePodStatus() + + val errors = ArrayList(); + if (omnipodPumpPlugin.rileyLinkService != null) { + val rileyLinkErrorDescription = omnipodPumpPlugin.rileyLinkService.errorDescription + if (StringUtils.isNotEmpty(rileyLinkErrorDescription)) { + errors.add(rileyLinkErrorDescription) + } + } + + if (!podStateManager.hasPodState() || !podStateManager.isPodInitialized) { + omnipod_pod_address.text = if (podStateManager.hasPodState()) { + podStateManager.address.toString() + } else { + PLACEHOLDER + } + omnipod_pod_lot.text = PLACEHOLDER + omnipod_pod_tid.text = PLACEHOLDER + omnipod_pod_firmware_version.text = PLACEHOLDER + omnipod_pod_expiry.text = PLACEHOLDER + omnipod_pod_expiry.setTextColor(Color.WHITE) + omnipod_base_basal_rate.text = PLACEHOLDER + omnipod_total_delivered.text = PLACEHOLDER + omnipod_reservoir.text = PLACEHOLDER + omnipod_pod_active_alerts.text = PLACEHOLDER + } else { + omnipod_pod_address.text = podStateManager.address.toString() + omnipod_pod_lot.text = podStateManager.lot.toString() + omnipod_pod_tid.text = podStateManager.tid.toString() + omnipod_pod_firmware_version.text = resourceHelper.gs(R.string.omnipod_pod_firmware_version_value, podStateManager.pmVersion.toString(), podStateManager.piVersion.toString()) + val expiresAt = podStateManager.expiresAt + if (expiresAt == null) { + omnipod_pod_expiry.text = PLACEHOLDER + omnipod_pod_expiry.setTextColor(Color.WHITE) + } else { + omnipod_pod_expiry.text = dateUtil.dateAndTimeString(expiresAt.toDate()) + omnipod_pod_expiry.setTextColor(if (DateTime.now().isAfter(expiresAt)) { + Color.RED + } else { + Color.WHITE + }) + } + + if (podStateManager.hasFaultEvent()) { + val faultEventCode = podStateManager.faultEvent.faultEventCode + errors.add(resourceHelper.gs(R.string.omnipod_pod_status_pod_fault_description, faultEventCode.value, faultEventCode.name)) + } + + val now = DateTime.now() + + // base basal rate + omnipod_base_basal_rate.text = if (podStateManager.isPodActivationCompleted) { + resourceHelper.gs(R.string.pump_basebasalrate, omnipodPumpPlugin.model().determineCorrectBasalSize(podStateManager.basalSchedule.rateAt(Duration(now.withTimeAtStartOfDay(), now)))) + } else { + PLACEHOLDER + } + + // total delivered + omnipod_total_delivered.text = if (podStateManager.isPodActivationCompleted && podStateManager.totalInsulinDelivered != null) { + resourceHelper.gs(R.string.omnipod_total_delivered, podStateManager.totalInsulinDelivered - OmnipodConstants.POD_SETUP_UNITS); + } else { + PLACEHOLDER + } + + // reservoir + if (podStateManager.reservoirLevel == null) { + omnipod_reservoir.text = resourceHelper.gs(R.string.omnipod_reservoir_over50) + omnipod_reservoir.setTextColor(Color.WHITE) + } else { + omnipod_reservoir.text = resourceHelper.gs(R.string.omnipod_reservoir_left, podStateManager.reservoirLevel) + warnColors.setColorInverse(omnipod_reservoir, podStateManager.reservoirLevel, 50.0, 20.0) + } + + omnipod_pod_active_alerts.text = if (podStateManager.hasActiveAlerts()) { + TextUtils.join(System.lineSeparator(), omnipodUtil.getTranslatedActiveAlerts(podStateManager)) + } else { + PLACEHOLDER + } + } + + if (errors.size == 0) { + omnipod_errors.text = PLACEHOLDER + omnipod_errors.setTextColor(Color.WHITE) + } else { + omnipod_errors.text = StringUtils.join(errors, System.lineSeparator()) + omnipod_errors.setTextColor(Color.RED) + } + } + + private fun updateLastConnection() { + if (podStateManager.isPodInitialized && podStateManager.lastSuccessfulCommunication != null) { + omnipod_last_connection.text = readableDuration(podStateManager.lastSuccessfulCommunication) + val lastConnectionColor = + if (omnipodPumpPlugin.isUnreachableAlertTimeoutExceeded(getPumpUnreachableTimeout().millis)) { + Color.RED + } else { + Color.WHITE + } + omnipod_last_connection.setTextColor(lastConnectionColor) + } else { + omnipod_last_connection.setTextColor(Color.WHITE) + omnipod_last_connection.text = if (podStateManager.hasPodState() && podStateManager.lastSuccessfulCommunication != null) { + readableDuration(podStateManager.lastSuccessfulCommunication) + } else { + PLACEHOLDER + } + } + } + + private fun updatePodStatus() { + omnipod_pod_status.text = if (!podStateManager.hasPodState()) { + resourceHelper.gs(R.string.omnipod_pod_status_no_active_pod) + } else if (!podStateManager.isPodActivationCompleted) { + if (!podStateManager.isPodInitialized) { + resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_pair_and_prime) + } else { + if (PodProgressStatus.ACTIVATION_TIME_EXCEEDED == podStateManager.podProgressStatus) { + resourceHelper.gs(R.string.omnipod_pod_status_activation_time_exceeded) + } else if (podStateManager.podProgressStatus.isBefore(PodProgressStatus.PRIMING_COMPLETED)) { + resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_pair_and_prime) + } else { + resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_cannula_insertion) + } + } + } else { + if (podStateManager.podProgressStatus.isRunning) { + if (podStateManager.isSuspended) { + resourceHelper.gs(R.string.omnipod_pod_status_suspended) + } else { + resourceHelper.gs(R.string.omnipod_pod_status_running) + } + } else if (podStateManager.podProgressStatus == PodProgressStatus.FAULT_EVENT_OCCURRED) { + resourceHelper.gs(R.string.omnipod_pod_status_pod_fault) + } else if (podStateManager.podProgressStatus == PodProgressStatus.INACTIVE) { + resourceHelper.gs(R.string.omnipod_pod_status_inactive) + } else { + podStateManager.podProgressStatus.toString() + } + } + + val podStatusColor = if (!podStateManager.isPodActivationCompleted || podStateManager.isPodDead || podStateManager.isSuspended) { + Color.RED + } else { + Color.WHITE + } + omnipod_pod_status.setTextColor(podStatusColor) + } + + private fun updateLastBolus() { + if (podStateManager.isPodActivationCompleted && podStateManager.hasLastBolus()) { + var text = resourceHelper.gs(R.string.omnipod_last_bolus, omnipodPumpPlugin.model().determineCorrectBolusSize(podStateManager.lastBolusAmount), resourceHelper.gs(R.string.insulin_unit_shortname), readableDuration(podStateManager.lastBolusStartTime)) + val textColor: Int + + if (podStateManager.isLastBolusCertain) { + textColor = Color.WHITE + } else { + textColor = Color.RED + text += " (" + resourceHelper.gs(R.string.omnipod_uncertain) + ")" + } + + omnipod_last_bolus.text = text; + omnipod_last_bolus.setTextColor(textColor) + + } else { + omnipod_last_bolus.text = PLACEHOLDER + omnipod_last_bolus.setTextColor(Color.WHITE) + } + } + + private fun updateTempBasal() { + if (podStateManager.isPodActivationCompleted && podStateManager.isTempBasalRunning) { + val now = DateTime.now() + + val startTime = podStateManager.tempBasalStartTime; + val amount = podStateManager.tempBasalAmount + val duration = podStateManager.tempBasalDuration; + + val minutesRunning = Duration(startTime, now).standardMinutes + + var text: String + val textColor: Int + text = resourceHelper.gs(R.string.omnipod_temp_basal, 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_temp_basal.text = text; + omnipod_temp_basal.setTextColor(textColor) + } else { + omnipod_temp_basal.text = PLACEHOLDER + omnipod_temp_basal.setTextColor(Color.WHITE) + } + } + + private fun updateQueueStatus() { + if (isQueueEmpty()) { + omnipod_queue.visibility = View.GONE + } else { + omnipod_queue.visibility = View.VISIBLE + omnipod_queue.text = commandQueue.spannedStatus().toString() + } + } + + private fun updatePodActionButtons() { + updateRefreshStatusButton() + updateResumeDeliveryButton() + updateAcknowledgeAlertsButton() + updateSuspendDeliveryButton() + updatePulseLogButton() + } + + private fun disablePodActionButtons() { + omnipod_button_acknowledge_active_alerts.isEnabled = false + omnipod_button_resume_delivery.isEnabled = false + omnipod_button_refresh_status.isEnabled = false + omnipod_button_pulse_log.isEnabled = false + } + + private fun updateRefreshStatusButton() { + omnipod_button_refresh_status.isEnabled = podStateManager.isPodInitialized && podStateManager.podProgressStatus.isAtLeast(PodProgressStatus.PAIRING_COMPLETED) + && rileyLinkServiceData.rileyLinkServiceState.isReady && isQueueEmpty() + } + + private fun updateResumeDeliveryButton() { + val queueEmptyOrStartingPump = isQueueEmpty() || commandQueue.isRunning(Command.CommandType.START_PUMP) + if (podStateManager.isPodActivationCompleted && podStateManager.isSuspended && queueEmptyOrStartingPump) { + omnipod_button_resume_delivery.visibility = View.VISIBLE + omnipod_button_resume_delivery.isEnabled = rileyLinkServiceData.rileyLinkServiceState.isReady && isQueueEmpty() + } else { + omnipod_button_resume_delivery.visibility = View.GONE + } + } + + private fun updateAcknowledgeAlertsButton() { + omnipod_button_acknowledge_active_alerts.isEnabled = podStateManager.isPodActivationCompleted && podStateManager.hasActiveAlerts() + && !podStateManager.isPodDead && rileyLinkServiceData.rileyLinkServiceState.isReady && isQueueEmpty() + } + + private fun updateSuspendDeliveryButton() { + // If the Pod is currently suspended, we show the Resume delivery button instead. + if (omnipodManager.isSuspendDeliveryButtonEnabled && !(podStateManager.isPodRunning && podStateManager.isSuspended)) { + omnipod_button_suspend_delivery.visibility = View.VISIBLE + omnipod_button_suspend_delivery.isEnabled = podStateManager.isPodRunning && !podStateManager.isSuspended && rileyLinkServiceData.rileyLinkServiceState.isReady && isQueueEmpty() + } else { + omnipod_button_suspend_delivery.visibility = View.GONE + } + } + + private fun updatePulseLogButton() { + if (omnipodManager.isPulseLogButtonEnabled) { + omnipod_button_pulse_log.visibility = View.VISIBLE + omnipod_button_pulse_log.isEnabled = podStateManager.isPodActivationCompleted && rileyLinkServiceData.rileyLinkServiceState.isReady && isQueueEmpty() + } else { + omnipod_button_pulse_log.visibility = View.GONE + } + } + + private fun displayNotConfiguredDialog() { + context?.let { + OKDialog.show(it, resourceHelper.gs(R.string.omnipod_warning), + resourceHelper.gs(R.string.omnipod_error_operation_not_possible_no_configuration), null) + } + } + + private fun readableDuration(dateTime: DateTime): String { + val duration = Duration(dateTime, DateTime.now()) + val hours = duration.standardHours.toInt() + val minutes = duration.standardMinutes.toInt() + val seconds = duration.standardSeconds.toInt() + when { + seconds < 10 -> { + return resourceHelper.gs(R.string.omnipod_moments_ago) + } + + seconds < 60 -> { + return resourceHelper.gs(R.string.omnipod_less_than_a_minute_ago) + } + + seconds < 60 * 60 -> { // < 1 hour + return resourceHelper.gs(R.string.omnipod_time_ago, resourceHelper.gq(R.plurals.omnipod_minutes, minutes, minutes)) + } + + seconds < 24 * 60 * 60 -> { // < 1 day + val minutesLeft = minutes % 60 + if (minutesLeft > 0) + return resourceHelper.gs(R.string.omnipod_time_ago, + resourceHelper.gs(R.string.omnipod_composite_time, resourceHelper.gq(R.plurals.omnipod_hours, hours, hours), resourceHelper.gq(R.plurals.omnipod_minutes, minutesLeft, minutesLeft))) + return resourceHelper.gs(R.string.omnipod_time_ago, resourceHelper.gq(R.plurals.omnipod_hours, hours, hours)) + } + + else -> { + val days = hours / 24 + val hoursLeft = hours % 24 + if (hoursLeft > 0) + return resourceHelper.gs(R.string.omnipod_time_ago, + resourceHelper.gs(R.string.omnipod_composite_time, resourceHelper.gq(R.plurals.omnipod_days, days, days), resourceHelper.gq(R.plurals.omnipod_hours, hoursLeft, hoursLeft))) + return resourceHelper.gs(R.string.omnipod_time_ago, resourceHelper.gq(R.plurals.omnipod_days, days, days)) + } + } + } + + private fun isQueueEmpty(): Boolean { + return commandQueue.size() == 0 && commandQueue.performing() == null + } + + // FIXME ideally we should just have access to LocalAlertUtils here + private fun getPumpUnreachableTimeout(): Duration { + return Duration.standardMinutes(sp.getInt(resourceHelper.gs(R.string.key_pump_unreachable_threshold_minutes), Constants.DEFAULT_PUMP_UNREACHABLE_THRESHOLD_MINUTES).toLong()) + } + +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/PodHistoryActivity.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/PodHistoryActivity.java similarity index 83% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/PodHistoryActivity.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/PodHistoryActivity.java index 51052e72eb..4913bb6614 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/PodHistoryActivity.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/PodHistoryActivity.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dialogs; +package info.nightscout.androidaps.plugins.pump.omnipod.ui; import android.os.Bundle; import android.os.SystemClock; @@ -34,14 +34,14 @@ import info.nightscout.androidaps.plugins.pump.common.defs.PumpHistoryEntryGroup 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.driver.db.PodHistoryEntryType; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil; +import info.nightscout.androidaps.plugins.pump.omnipod.definition.PodHistoryEntryType; +import info.nightscout.androidaps.plugins.pump.omnipod.util.AapsOmnipodUtil; import info.nightscout.androidaps.utils.resources.ResourceHelper; public class PodHistoryActivity extends NoSplashAppCompatActivity { @Inject AAPSLogger aapsLogger; - @Inject OmnipodUtil omnipodUtil; + @Inject AapsOmnipodUtil aapsOmnipodUtil; @Inject ResourceHelper resourceHelper; @Inject DatabaseHelperInterface databaseHelper; @@ -50,15 +50,14 @@ public class PodHistoryActivity extends NoSplashAppCompatActivity { private RecyclerView recyclerView; private LinearLayoutManager linearLayoutManager; - static TypeList showingType = null; - static PumpHistoryEntryGroup selectedGroup = PumpHistoryEntryGroup.All; - List fullHistoryList = new ArrayList<>(); - List filteredHistoryList = new ArrayList<>(); + private static PumpHistoryEntryGroup selectedGroup = PumpHistoryEntryGroup.All; + private final List fullHistoryList = new ArrayList<>(); + private final List filteredHistoryList = new ArrayList<>(); - RecyclerViewAdapter recyclerViewAdapter; - boolean manualChange = false; + private RecyclerViewAdapter recyclerViewAdapter; + private boolean manualChange = false; - List typeListFull; + private List typeListFull; public PodHistoryActivity() { @@ -162,7 +161,6 @@ public class PodHistoryActivity extends NoSplashAppCompatActivity { if (manualChange) return; TypeList selected = (TypeList) historyTypeSpinner.getSelectedItem(); - showingType = selected; selectedGroup = selected.entryGroup; filterHistory(selectedGroup); } @@ -190,10 +188,10 @@ public class PodHistoryActivity extends NoSplashAppCompatActivity { return typeList; } - public static class TypeList { + static class TypeList { - PumpHistoryEntryGroup entryGroup; - String name; + final PumpHistoryEntryGroup entryGroup; + final String name; TypeList(PumpHistoryEntryGroup entryGroup) { this.entryGroup = entryGroup; @@ -216,7 +214,7 @@ public class PodHistoryActivity extends NoSplashAppCompatActivity { } - public void setHistoryList(List historyList) { + void setHistoryList(List historyList) { this.historyList = historyList; Collections.sort(this.historyList); } @@ -250,21 +248,21 @@ public class PodHistoryActivity extends NoSplashAppCompatActivity { PodHistoryEntryType entryType = PodHistoryEntryType.getByCode(historyEntry.getPodEntryTypeCode()); switch (entryType) { - case SetTemporaryBasal: { - TempBasalPair tempBasalPair = omnipodUtil.getGsonInstance().fromJson(historyEntry.getData(), TempBasalPair.class); + case SET_TEMPORARY_BASAL: { + TempBasalPair tempBasalPair = aapsOmnipodUtil.getGsonInstance().fromJson(historyEntry.getData(), TempBasalPair.class); valueView.setText(resourceHelper.gs(R.string.omnipod_cmd_tbr_value, tempBasalPair.getInsulinRate(), tempBasalPair.getDurationMinutes())); } break; - case FillCannulaSetBasalProfile: - case SetBasalSchedule: { + case FILL_CANNULA_SET_BASAL_PROFILE: + case SET_BASAL_SCHEDULE: { if (historyEntry.getData() != null) { setProfileValue(historyEntry.getData(), valueView); } } break; - case SetBolus: { + case SET_BOLUS: { if (historyEntry.getData().contains(";")) { String[] splitVal = historyEntry.getData().split(";"); valueView.setText(resourceHelper.gs(R.string.omnipod_cmd_bolus_value_with_carbs, Double.valueOf(splitVal[0]), Double.valueOf(splitVal[1]))); @@ -274,20 +272,20 @@ public class PodHistoryActivity extends NoSplashAppCompatActivity { } break; - case GetPodStatus: - case GetPodInfo: - case SetTime: - case PairAndPrime: - case CancelTemporaryBasal: - case CancelTemporaryBasalForce: - case ConfigureAlerts: - case CancelBolus: - case DeactivatePod: - case ResetPodState: - case AcknowledgeAlerts: - case SuspendDelivery: - case ResumeDelivery: - case UnknownEntryType: + case GET_POD_STATUS: + case GET_POD_INFO: + case SET_TIME: + case PAIR_AND_PRIME: + case CANCEL_TEMPORARY_BASAL_BY_DRIVER: + case CANCEL_TEMPORARY_BASAL: + case CONFIGURE_ALERTS: + case CANCEL_BOLUS: + case DEACTIVATE_POD: + case RESET_POD_STATE: + case ACKNOWLEDGE_ALERTS: + case SUSPEND_DELIVERY: + case RESUME_DELIVERY: + case UNKNOWN_ENTRY_TYPE: default: valueView.setText(""); break; @@ -303,7 +301,7 @@ public class PodHistoryActivity extends NoSplashAppCompatActivity { aapsLogger.debug(LTag.PUMP, "Profile json:\n" + data); try { - Profile.ProfileValue[] profileValuesArray = omnipodUtil.getGsonInstance().fromJson(data, Profile.ProfileValue[].class); + Profile.ProfileValue[] profileValuesArray = aapsOmnipodUtil.getGsonInstance().fromJson(data, Profile.ProfileValue[].class); valueView.setText(ProfileUtil.getBasalProfilesDisplayable(profileValuesArray, PumpType.Insulet_Omnipod)); } catch (Exception e) { aapsLogger.error(LTag.PUMP, "Problem parsing Profile json. Ex: {}, Data:\n{}", e.getMessage(), data); @@ -326,9 +324,9 @@ public class PodHistoryActivity extends NoSplashAppCompatActivity { class HistoryViewHolder extends RecyclerView.ViewHolder { - TextView timeView; - TextView typeView; - TextView valueView; + final TextView timeView; + final TextView typeView; + final TextView valueView; HistoryViewHolder(View itemView) { super(itemView); diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/PodManagementActivity.kt b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/PodManagementActivity.kt similarity index 79% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/PodManagementActivity.kt rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/PodManagementActivity.kt index 47ef877239..43f4046a5e 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/PodManagementActivity.kt +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/PodManagementActivity.kt @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dialogs +package info.nightscout.androidaps.plugins.pump.omnipod.ui import android.content.Intent import android.os.Bundle @@ -11,20 +11,20 @@ import com.atech.android.library.wizardpager.data.WizardPagerSettings import com.atech.android.library.wizardpager.defs.WizardStepsWayType import dagger.android.HasAndroidInjector import info.nightscout.androidaps.activities.NoSplashAppCompatActivity -import info.nightscout.androidaps.events.EventRefreshOverview 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.service.RileyLinkServiceData import info.nightscout.androidaps.plugins.pump.omnipod.R -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodProgressStatus -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager -import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.defs.PodActionType -import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.model.FullInitPodWizardModel -import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.model.RemovePodWizardModel -import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.model.ShortInitPodWizardModel -import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.pages.InitPodRefreshAction -import info.nightscout.androidaps.plugins.pump.omnipod.driver.comm.AapsOmnipodManager +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager +import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged +import info.nightscout.androidaps.plugins.pump.omnipod.manager.AapsOmnipodManager +import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.defs.PodActionType +import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.model.FullInitPodWizardModel +import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.model.RemovePodWizardModel +import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.model.ShortInitPodWizardModel +import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.pages.InitPodRefreshAction import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.extensions.plusAssign @@ -59,11 +59,11 @@ class PodManagementActivity : NoSplashAppCompatActivity() { } initpod_remove_pod.setOnClickListener { - removePodAction() + deactivatePodAction() } initpod_reset_pod.setOnClickListener { - resetPodAction() + discardPodAction() } initpod_pod_history.setOnClickListener { @@ -77,6 +77,10 @@ class PodManagementActivity : NoSplashAppCompatActivity() { .toObservable(EventRileyLinkDeviceStatusChange::class.java) .observeOn(AndroidSchedulers.mainThread()) .subscribe({ refreshButtons() }, { fabricPrivacy.logException(it) }) + disposables += rxBus + .toObservable(EventOmnipodPumpValuesChanged::class.java) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ refreshButtons() }, { fabricPrivacy.logException(it) }) refreshButtons() } @@ -86,15 +90,10 @@ class PodManagementActivity : NoSplashAppCompatActivity() { disposables.clear() } - override fun onDestroy() { - super.onDestroy() - rxBus.send(EventRefreshOverview("Omnipod Pod Management")) - } - - fun initPodAction() { + private fun initPodAction() { val pagerSettings = WizardPagerSettings() - var refreshAction = InitPodRefreshAction(injector, PodActionType.InitPod) + var refreshAction = InitPodRefreshAction(injector, PodActionType.INIT_POD) pagerSettings.setWizardStepsWayType(WizardStepsWayType.CancelNext) pagerSettings.setFinishStringResourceId(R.string.close) @@ -120,9 +119,9 @@ class PodManagementActivity : NoSplashAppCompatActivity() { this@PodManagementActivity.startActivity(myIntent) } - fun removePodAction() { + private fun deactivatePodAction() { val pagerSettings = WizardPagerSettings() - var refreshAction = InitPodRefreshAction(injector, PodActionType.RemovePod) + var refreshAction = InitPodRefreshAction(injector, PodActionType.DEACTIVATE_POD) pagerSettings.setWizardStepsWayType(WizardStepsWayType.CancelNext) pagerSettings.setFinishStringResourceId(R.string.close) @@ -144,19 +143,19 @@ class PodManagementActivity : NoSplashAppCompatActivity() { } - fun resetPodAction() { + private fun discardPodAction() { OKDialog.showConfirmation(this, - resourceHelper.gs(R.string.omnipod_cmd_reset_pod_desc), Thread { - aapsOmnipodManager.resetPodStatus() - refreshButtons() + resourceHelper.gs(R.string.omnipod_cmd_discard_pod_desc), Thread { + aapsOmnipodManager.discardPodState() + rxBus.send(EventOmnipodPumpValuesChanged()) }) } - fun showPodHistory() { + private fun showPodHistory() { startActivity(Intent(applicationContext, PodHistoryActivity::class.java)) } - fun refreshButtons() { + private fun refreshButtons() { initpod_init_pod.isEnabled = !podStateManager.isPodActivationCompleted initpod_remove_pod.isEnabled = podStateManager.isPodInitialized initpod_reset_pod.isEnabled = podStateManager.hasPodState() diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/defs/PodActionType.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/defs/PodActionType.java new file mode 100644 index 0000000000..48380638c2 --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/defs/PodActionType.java @@ -0,0 +1,7 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.defs; + +public enum PodActionType { + INIT_POD, + DEACTIVATE_POD, + DISCARD_POD +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/initpod/InitActionFragment.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/initpod/InitActionFragment.java similarity index 91% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/initpod/InitActionFragment.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/initpod/InitActionFragment.java index 192dde6c26..e05c86ec5b 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/initpod/InitActionFragment.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/initpod/InitActionFragment.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.initpod; +package info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.initpod; import android.annotation.SuppressLint; import android.content.Context; @@ -32,8 +32,8 @@ import dagger.android.HasAndroidInjector; import dagger.android.support.DaggerFragment; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.plugins.pump.omnipod.R; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInitActionType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInitReceiver; +import info.nightscout.androidaps.plugins.pump.omnipod.definition.PodInitActionType; +import info.nightscout.androidaps.plugins.pump.omnipod.definition.PodInitReceiver; /** * Created by andy on 12/11/2019 @@ -44,16 +44,16 @@ public class InitActionFragment extends DaggerFragment implements PodInitReceive private static boolean isFirstView; - protected PageFragmentCallbacks mCallbacks; - protected String mKey; + private PageFragmentCallbacks mCallbacks; + private String mKey; protected InitActionPage mPage; protected ProgressBar progressBar; protected TextView errorView; protected Button retryButton; - protected PodInitActionType podInitActionType; - protected List children; + PodInitActionType podInitActionType; + private List children; protected Map mapCheckBoxes; protected PumpEnactResult callResult; @@ -118,9 +118,9 @@ public class InitActionFragment extends DaggerFragment implements PodInitReceive mapCheckBoxes.put(child, checkBox1); } - if (podInitActionType == PodInitActionType.FillCannulaSetBasalProfileWizardStep) { + if (podInitActionType == PodInitActionType.FILL_CANNULA_SET_BASAL_PROFILE_WIZARD_STEP) { headerView.setText(R.string.omnipod_init_pod_wizard_step4_action_header); - } else if (podInitActionType == PodInitActionType.DeactivatePodWizardStep) { + } else if (podInitActionType == PodInitActionType.DEACTIVATE_POD_WIZARD_STEP) { headerView.setText(R.string.omnipod_remove_pod_wizard_step2_action_header); } @@ -209,7 +209,7 @@ public class InitActionFragment extends DaggerFragment implements PodInitReceive } } - public void setCheckBox(PodInitActionType podInitActionType, boolean isSuccess) { + protected void setCheckBox(PodInitActionType podInitActionType, boolean isSuccess) { FragmentActivity activity = getActivity(); if (activity != null) { activity.runOnUiThread(() -> { diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/initpod/InitActionPage.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/initpod/InitActionPage.java similarity index 79% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/initpod/InitActionPage.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/initpod/InitActionPage.java index 3ba9145749..8c086ffe6e 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/initpod/InitActionPage.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/initpod/InitActionPage.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.initpod; +package info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.initpod; import androidx.annotation.StringRes; import androidx.fragment.app.Fragment; @@ -9,7 +9,7 @@ import com.tech.freak.wizardpager.model.ReviewItem; import java.util.ArrayList; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInitActionType; +import info.nightscout.androidaps.plugins.pump.omnipod.definition.PodInitActionType; /** @@ -21,10 +21,10 @@ public class InitActionPage extends Page { protected PodInitActionType podInitActionType; - protected boolean actionCompleted = false; - protected boolean actionSuccess = false; + private boolean actionCompleted = false; + private boolean actionSuccess = false; - public InitActionPage(ModelCallbacks callbacks, String title) { + protected InitActionPage(ModelCallbacks callbacks, String title) { super(callbacks, title); } @@ -57,7 +57,7 @@ public class InitActionPage extends Page { * * @return */ - public boolean isBackActionPossible() { + @Override public boolean isBackActionPossible() { return actionCompleted; } @@ -66,7 +66,7 @@ public class InitActionPage extends Page { * * @return */ - public boolean isNextActionPossible() { + @Override public boolean isNextActionPossible() { return actionSuccess; } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/initpod/InitPodTask.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/initpod/InitPodTask.java similarity index 65% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/initpod/InitPodTask.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/initpod/InitPodTask.java index 5496843cf9..12742ff108 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/initpod/InitPodTask.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/initpod/InitPodTask.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.initpod; +package info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.initpod; import android.os.AsyncTask; import android.view.View; @@ -7,8 +7,10 @@ import javax.inject.Inject; import dagger.android.HasAndroidInjector; import info.nightscout.androidaps.interfaces.ProfileFunction; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInitActionType; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.comm.AapsOmnipodManager; +import info.nightscout.androidaps.plugins.bus.RxBusWrapper; +import info.nightscout.androidaps.plugins.pump.omnipod.definition.PodInitActionType; +import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged; +import info.nightscout.androidaps.plugins.pump.omnipod.manager.AapsOmnipodManager; /** * Created by andy on 11/12/2019 @@ -17,7 +19,8 @@ public class InitPodTask extends AsyncTask { @Inject ProfileFunction profileFunction; @Inject AapsOmnipodManager aapsOmnipodManager; - private InitActionFragment initActionFragment; + @Inject RxBusWrapper rxBus; + private final InitActionFragment initActionFragment; public InitPodTask(HasAndroidInjector injector, InitActionFragment initActionFragment) { injector.androidInjector().inject(this); @@ -34,22 +37,23 @@ public class InitPodTask extends AsyncTask { @Override protected String doInBackground(Void... params) { - if (initActionFragment.podInitActionType == PodInitActionType.PairAndPrimeWizardStep) { - initActionFragment.callResult = aapsOmnipodManager.initPod( + if (initActionFragment.podInitActionType == PodInitActionType.PAIR_AND_PRIME_WIZARD_STEP) { + initActionFragment.callResult = aapsOmnipodManager.pairAndPrime( initActionFragment.podInitActionType, - initActionFragment, - null + initActionFragment ); - } else if (initActionFragment.podInitActionType == PodInitActionType.FillCannulaSetBasalProfileWizardStep) { - initActionFragment.callResult = aapsOmnipodManager.initPod( + } else if (initActionFragment.podInitActionType == PodInitActionType.FILL_CANNULA_SET_BASAL_PROFILE_WIZARD_STEP) { + initActionFragment.callResult = aapsOmnipodManager.setInitialBasalScheduleAndInsertCannula( initActionFragment.podInitActionType, initActionFragment, profileFunction.getProfile() ); - } else if (initActionFragment.podInitActionType == PodInitActionType.DeactivatePodWizardStep) { + } else if (initActionFragment.podInitActionType == PodInitActionType.DEACTIVATE_POD_WIZARD_STEP) { initActionFragment.callResult = aapsOmnipodManager.deactivatePod(initActionFragment); } + rxBus.send(new EventOmnipodPumpValuesChanged()); + return "OK"; } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/model/FullInitPodWizardModel.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/model/FullInitPodWizardModel.java similarity index 80% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/model/FullInitPodWizardModel.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/model/FullInitPodWizardModel.java index 7c70f64c2c..af364324ae 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/model/FullInitPodWizardModel.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/model/FullInitPodWizardModel.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.model; +package info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.model; import android.content.Context; @@ -6,8 +6,8 @@ import com.atech.android.library.wizardpager.model.DisplayTextPage; import com.tech.freak.wizardpager.model.PageList; import info.nightscout.androidaps.plugins.pump.omnipod.R; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInitActionType; -import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.initpod.InitActionPage; +import info.nightscout.androidaps.plugins.pump.omnipod.definition.PodInitActionType; +import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.initpod.InitActionPage; /** * Created by andy on 12/11/2019 @@ -31,7 +31,7 @@ public class FullInitPodWizardModel extends InitPodWizardModel { new InitActionPage(this, R.string.omnipod_init_pod_wizard_step2_title, - PodInitActionType.PairAndPrimeWizardStep + PodInitActionType.PAIR_AND_PRIME_WIZARD_STEP ).setRequired(true).setCancelReason("Cancel"), new DisplayTextPage(this, @@ -41,7 +41,7 @@ public class FullInitPodWizardModel extends InitPodWizardModel { new InitActionPage(this, R.string.omnipod_init_pod_wizard_step4_title, - PodInitActionType.FillCannulaSetBasalProfileWizardStep + PodInitActionType.FILL_CANNULA_SET_BASAL_PROFILE_WIZARD_STEP ).setRequired(true).setCancelReason("Cancel") ); } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/model/InitPodWizardModel.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/model/InitPodWizardModel.java new file mode 100644 index 0000000000..e3c4e9c1fe --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/model/InitPodWizardModel.java @@ -0,0 +1,20 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.model; + +import android.content.Context; + +import androidx.fragment.app.Fragment; + +import com.tech.freak.wizardpager.model.AbstractWizardModel; + +import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.pages.PodInfoFragment; + +abstract class InitPodWizardModel extends AbstractWizardModel { + InitPodWizardModel(Context context) { + super(context); + } + + @Override + public Fragment getReviewFragment() { + return PodInfoFragment.create(true); + } +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/model/RemovePodWizardModel.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/model/RemovePodWizardModel.java similarity index 75% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/model/RemovePodWizardModel.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/model/RemovePodWizardModel.java index c0088984b4..381dcb1950 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/model/RemovePodWizardModel.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/model/RemovePodWizardModel.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.model; +package info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.model; import android.content.Context; @@ -25,9 +25,9 @@ import com.tech.freak.wizardpager.model.AbstractWizardModel; import com.tech.freak.wizardpager.model.PageList; import info.nightscout.androidaps.plugins.pump.omnipod.R; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInitActionType; -import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.pages.PodInfoFragment; -import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.removepod.RemovePodActionPage; +import info.nightscout.androidaps.plugins.pump.omnipod.definition.PodInitActionType; +import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.pages.PodInfoFragment; +import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.removepod.RemovePodActionPage; /** * Created by andy on 12/11/2019 @@ -48,14 +48,14 @@ public class RemovePodWizardModel extends AbstractWizardModel { new RemovePodActionPage(this, R.string.omnipod_remove_pod_wizard_step2_title, - PodInitActionType.DeactivatePodWizardStep + PodInitActionType.DEACTIVATE_POD_WIZARD_STEP ).setRequired(true).setCancelReason("Cancel") ); } - public Fragment getReviewFragment() { - return PodInfoFragment.create("removePodInfoFragment", false); + @Override public Fragment getReviewFragment() { + return PodInfoFragment.create(false); } } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/model/ShortInitPodWizardModel.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/model/ShortInitPodWizardModel.java similarity index 78% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/model/ShortInitPodWizardModel.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/model/ShortInitPodWizardModel.java index 51676a20a6..3813520e80 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/model/ShortInitPodWizardModel.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/model/ShortInitPodWizardModel.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.model; +package info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.model; import android.content.Context; @@ -6,8 +6,8 @@ import com.atech.android.library.wizardpager.model.DisplayTextPage; import com.tech.freak.wizardpager.model.PageList; import info.nightscout.androidaps.plugins.pump.omnipod.R; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInitActionType; -import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.initpod.InitActionPage; +import info.nightscout.androidaps.plugins.pump.omnipod.definition.PodInitActionType; +import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.initpod.InitActionPage; /** * Created by andy on 12/11/2019 @@ -31,7 +31,7 @@ public class ShortInitPodWizardModel extends InitPodWizardModel { new InitActionPage(this, R.string.omnipod_init_pod_wizard_step4_title, - PodInitActionType.FillCannulaSetBasalProfileWizardStep + PodInitActionType.FILL_CANNULA_SET_BASAL_PROFILE_WIZARD_STEP ).setRequired(true).setCancelReason("Cancel") ); diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/pages/InitPodRefreshAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/pages/InitPodRefreshAction.java similarity index 73% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/pages/InitPodRefreshAction.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/pages/InitPodRefreshAction.java index 80935bad7c..9f7c47be2b 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/pages/InitPodRefreshAction.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/pages/InitPodRefreshAction.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.pages; +package info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.pages; import com.atech.android.library.wizardpager.defs.action.AbstractCancelAction; import com.atech.android.library.wizardpager.defs.action.FinishActionInterface; @@ -12,11 +12,12 @@ import dagger.android.HasAndroidInjector; import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.interfaces.DatabaseHelperInterface; +import info.nightscout.androidaps.interfaces.ProfileFunction; import info.nightscout.androidaps.logging.AAPSLogger; import info.nightscout.androidaps.logging.LTag; import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; -import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.defs.PodActionType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.defs.PodActionType; import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.sharedPreferences.SP; @@ -26,15 +27,18 @@ import info.nightscout.androidaps.utils.sharedPreferences.SP; */ public class InitPodRefreshAction extends AbstractCancelAction implements FinishActionInterface { - private PodActionType actionType; + private final PodActionType actionType; + private final HasAndroidInjector injector; @Inject PodStateManager podStateManager; @Inject AAPSLogger aapsLogger; @Inject SP sp; @Inject NSUpload nsUpload; @Inject DatabaseHelperInterface databaseHelper; + @Inject ProfileFunction profileFunction; public InitPodRefreshAction(HasAndroidInjector injector, PodActionType actionType) { + this.injector = injector; injector.androidInjector().inject(this); this.actionType = actionType; } @@ -48,8 +52,10 @@ public class InitPodRefreshAction extends AbstractCancelAction implements Finish @Override public void execute() { - if (actionType == PodActionType.InitPod) { + if (actionType == PodActionType.INIT_POD) { if (podStateManager.isPodRunning()) { + uploadCareportalEvent(System.currentTimeMillis() - 2000, CareportalEvent.PUMPBATTERYCHANGE); + uploadCareportalEvent(System.currentTimeMillis() - 1000, CareportalEvent.INSULINCHANGE); uploadCareportalEvent(System.currentTimeMillis(), CareportalEvent.SITECHANGE); } } @@ -61,10 +67,14 @@ public class InitPodRefreshAction extends AbstractCancelAction implements Finish try { JSONObject data = new JSONObject(); String enteredBy = sp.getString("careportal_enteredby", ""); - if (!enteredBy.equals("")) data.put("enteredBy", enteredBy); + if (enteredBy.isEmpty()) { + data.put("enteredBy", enteredBy); + } data.put("created_at", DateUtil.toISOString(date)); + data.put("mills", date); data.put("eventType", event); - CareportalEvent careportalEvent = new CareportalEvent(); + data.put("units", profileFunction.getUnits()); + CareportalEvent careportalEvent = new CareportalEvent(injector); careportalEvent.date = date; careportalEvent.source = Source.USER; careportalEvent.eventType = event; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/pages/PodInfoFragment.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/pages/PodInfoFragment.java similarity index 83% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/pages/PodInfoFragment.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/pages/PodInfoFragment.java index 0d4f3c52c6..83dbeb0125 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/pages/PodInfoFragment.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/pages/PodInfoFragment.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.pages; +package info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.pages; import android.annotation.SuppressLint; import android.content.Context; @@ -22,28 +22,24 @@ import javax.inject.Inject; import dagger.android.support.DaggerFragment; import info.nightscout.androidaps.plugins.pump.omnipod.R; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; -import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.util.AapsOmnipodUtil; /** * Created by andy on 12/11/2019 */ public class PodInfoFragment extends DaggerFragment { - private static final String ARG_KEY = "key"; private static final String ARG_INIT_POD = "initPod"; - @Inject OmnipodUtil omnipodUtil; + @Inject AapsOmnipodUtil aapsOmnipodUtil; @Inject PodStateManager podStateManager; - private PageFragmentCallbacks mCallbacks; - private String mKey; - public boolean isInitPod; + private boolean isInitPod; private ArrayList mCurrentReviewItems; - public static PodInfoFragment create(String key, boolean initPod) { + public static PodInfoFragment create(boolean initPod) { Bundle args = new Bundle(); - args.putString(ARG_KEY, key); args.putBoolean(ARG_INIT_POD, initPod); PodInfoFragment fragment = new PodInfoFragment(); @@ -58,7 +54,6 @@ public class PodInfoFragment extends DaggerFragment { getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); Bundle args = getArguments(); - mKey = args.getString(ARG_KEY); isInitPod = args.getBoolean(ARG_INIT_POD); } @@ -120,28 +115,16 @@ public class PodInfoFragment extends DaggerFragment { if (!(activity instanceof PageFragmentCallbacks)) { throw new ClassCastException("Activity must implement PageFragmentCallbacks"); } - - mCallbacks = (PageFragmentCallbacks) activity; } @Override public void onDetach() { super.onDetach(); - mCallbacks = null; } - private class PodInfoAdapter extends ArrayAdapter { - - private ArrayList dataSet; - Context mContext; - private int lastPosition = -1; - - // View lookup cache - - public PodInfoAdapter(ArrayList data, Context context) { + private static class PodInfoAdapter extends ArrayAdapter { + PodInfoAdapter(ArrayList data, Context context) { super(context, com.tech.freak.wizardpager.R.layout.list_item_review, data); - this.dataSet = data; - this.mContext = context; } @@ -152,8 +135,6 @@ public class PodInfoFragment extends DaggerFragment { // Check if an existing view is being reused, otherwise inflate the view ViewHolder viewHolder; // view lookup cache stored in tag - final View result; - if (convertView == null) { viewHolder = new ViewHolder(); @@ -162,12 +143,9 @@ public class PodInfoFragment extends DaggerFragment { viewHolder.txtName = (TextView) convertView.findViewById(android.R.id.text1); viewHolder.txtType = (TextView) convertView.findViewById(android.R.id.text2); - result = convertView; - convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); - result = convertView; } viewHolder.txtName.setText(dataModel.getTitle()); diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/removepod/RemoveActionFragment.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/removepod/RemoveActionFragment.java similarity index 82% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/removepod/RemoveActionFragment.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/removepod/RemoveActionFragment.java index 935ee65085..2ca5a1d198 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/removepod/RemoveActionFragment.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/removepod/RemoveActionFragment.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.removepod; +package info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.removepod; import android.os.Bundle; import android.view.View; @@ -7,9 +7,9 @@ import com.tech.freak.wizardpager.model.Page; import java.util.UUID; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInitActionType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInitReceiver; -import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.initpod.InitActionFragment; +import info.nightscout.androidaps.plugins.pump.omnipod.definition.PodInitActionType; +import info.nightscout.androidaps.plugins.pump.omnipod.definition.PodInitReceiver; +import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.initpod.InitActionFragment; /** * Created by andy on 29/11/2019 diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/removepod/RemovePodActionPage.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/removepod/RemovePodActionPage.java similarity index 72% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/removepod/RemovePodActionPage.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/removepod/RemovePodActionPage.java index 444c8a4b11..7d1b319d8c 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dialogs/wizard/removepod/RemovePodActionPage.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/removepod/RemovePodActionPage.java @@ -1,12 +1,12 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.removepod; +package info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.removepod; import androidx.annotation.StringRes; import androidx.fragment.app.Fragment; import com.tech.freak.wizardpager.model.ModelCallbacks; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInitActionType; -import info.nightscout.androidaps.plugins.pump.omnipod.dialogs.wizard.initpod.InitActionPage; +import info.nightscout.androidaps.plugins.pump.omnipod.definition.PodInitActionType; +import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.initpod.InitActionPage; /** diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodUtil.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/AapsOmnipodUtil.java similarity index 86% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodUtil.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/AapsOmnipodUtil.java index ddc0022372..97c938825a 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodUtil.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/AapsOmnipodUtil.java @@ -17,24 +17,24 @@ import javax.inject.Inject; import javax.inject.Singleton; import info.nightscout.androidaps.plugins.pump.omnipod.R; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSet; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertSlot; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.AlertType; -import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodStateManager; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertSet; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertSlot; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; import info.nightscout.androidaps.utils.resources.ResourceHelper; /** * Created by andy on 4/8/19. */ @Singleton -public class OmnipodUtil { +public class AapsOmnipodUtil { private final ResourceHelper resourceHelper; - private Gson gsonInstance = createGson(); + private final Gson gsonInstance = createGson(); @Inject - public OmnipodUtil(ResourceHelper resourceHelper) { + public AapsOmnipodUtil(ResourceHelper resourceHelper) { this.resourceHelper = resourceHelper; } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodAlertUtil.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodAlertUtil.java new file mode 100644 index 0000000000..f9e541f986 --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/util/OmnipodAlertUtil.java @@ -0,0 +1,29 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.util; + +import org.joda.time.Duration; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import info.nightscout.androidaps.plugins.pump.omnipod.definition.OmnipodStorageKeys; +import info.nightscout.androidaps.utils.sharedPreferences.SP; + +@Singleton +public class OmnipodAlertUtil { + private final SP sp; + + @Inject + public OmnipodAlertUtil(SP sp) { + this.sp = sp; + } + + public Duration getExpirationReminderTimeBeforeShutdown() { + boolean expirationAlertEnabled = sp.getBoolean(OmnipodStorageKeys.Preferences.EXPIRATION_REMINDER_ENABLED, true); + return expirationAlertEnabled ? Duration.standardHours(sp.getInt(OmnipodStorageKeys.Preferences.EXPIRATION_REMINDER_HOURS_BEFORE_SHUTDOWN, 9)) : null; + } + + public Integer getLowReservoirAlertUnits() { + boolean lowReservoirAlertEnabled = sp.getBoolean(OmnipodStorageKeys.Preferences.LOW_RESERVOIR_ALERT_ENABLED, true); + return lowReservoirAlertEnabled ? sp.getInt(OmnipodStorageKeys.Preferences.LOW_RESERVOIR_ALERT_UNITS, 20) : null; + } +} diff --git a/omnipod/src/main/res/drawable/ic_cp_aaps_offline.xml b/omnipod/src/main/res/drawable/ic_cp_aaps_offline.xml new file mode 100644 index 0000000000..0b267a6d88 --- /dev/null +++ b/omnipod/src/main/res/drawable/ic_cp_aaps_offline.xml @@ -0,0 +1,21 @@ + + + + + + + diff --git a/omnipod/src/main/res/drawable/ic_cp_bolus_correction.xml b/omnipod/src/main/res/drawable/ic_cp_bolus_correction.xml new file mode 100644 index 0000000000..e14bb7c14f --- /dev/null +++ b/omnipod/src/main/res/drawable/ic_cp_bolus_correction.xml @@ -0,0 +1,12 @@ + + + + diff --git a/omnipod/src/main/res/drawable/ic_exit_to_app.xml b/omnipod/src/main/res/drawable/ic_exit_to_app.xml new file mode 100644 index 0000000000..37a6c7d058 --- /dev/null +++ b/omnipod/src/main/res/drawable/ic_exit_to_app.xml @@ -0,0 +1,12 @@ + + + + diff --git a/omnipod/src/main/res/drawable/ic_local_activate.xml b/omnipod/src/main/res/drawable/ic_local_activate.xml new file mode 100644 index 0000000000..905ade57d3 --- /dev/null +++ b/omnipod/src/main/res/drawable/ic_local_activate.xml @@ -0,0 +1,12 @@ + + + + diff --git a/omnipod/src/main/res/drawable/ic_loop_disabled.xml b/omnipod/src/main/res/drawable/ic_loop_disabled.xml new file mode 100644 index 0000000000..ed79c96429 --- /dev/null +++ b/omnipod/src/main/res/drawable/ic_loop_disabled.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/omnipod/src/main/res/layout/omnipod_fragment.xml b/omnipod/src/main/res/layout/omnipod_fragment.xml index bf4f6af6e5..cad9139a1a 100644 --- a/omnipod/src/main/res/layout/omnipod_fragment.xml +++ b/omnipod/src/main/res/layout/omnipod_fragment.xml @@ -2,7 +2,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context="info.nightscout.androidaps.plugins.pump.omnipod.OmnipodFragment"> + tools:context="info.nightscout.androidaps.plugins.pump.omnipod.ui.OmnipodFragment"> + + + + + + + + + + + + - - - - - - - - - - - - -