Merge branch 'omnipod_eros_dev' into omnipod_eros_dev_upstream_merge
This commit is contained in:
commit
a708aad267
53 changed files with 1066 additions and 430 deletions
33
.github/workflows/gradle-ci-workflow.yaml
vendored
Normal file
33
.github/workflows/gradle-ci-workflow.yaml
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
name: Gradle CI
|
||||
|
||||
on:
|
||||
- push
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK 1.8
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.8
|
||||
- name: Create NDK path
|
||||
run: sudo mkdir -p /usr/local/lib/android/sdk/ndk && sudo chmod 777 /usr/local/lib/android/sdk/ndk
|
||||
- name: Cache NDKs
|
||||
id: cache-ndk
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: /usr/local/lib/android/sdk/ndk
|
||||
key: ${{ runner.os }}-ndk-21.0.6113669-21.1.6352462
|
||||
- name: Install NDK 21.0.6113669
|
||||
run: echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;21.0.6113669" --sdk_root=${ANDROID_SDK_ROOT}
|
||||
- name: Install NDK 21.1.6352462
|
||||
run: echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;21.1.6352462" --sdk_root=${ANDROID_SDK_ROOT}
|
||||
- uses: eskatos/gradle-command-action@v1
|
||||
with:
|
||||
arguments: assembleFullDebug
|
||||
wrapper-cache-enabled: true
|
||||
dependencies-cache-enabled: true
|
||||
configuration-cache-enabled: true
|
|
@ -126,7 +126,7 @@ android {
|
|||
targetSdkVersion 28
|
||||
multiDexEnabled true
|
||||
versionCode 1500
|
||||
version "2.6.7-dev"
|
||||
version "2.7-omnipod-0.4.1-SNAPSHOT"
|
||||
buildConfigField "String", "VERSION", '"' + version + '"'
|
||||
buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"'
|
||||
buildConfigField "String", "REMOTE", '"' + generateGitRemote() + '"'
|
||||
|
@ -245,6 +245,7 @@ dependencies {
|
|||
implementation project(':danar')
|
||||
implementation project(':rileylink')
|
||||
implementation project(':medtronic')
|
||||
implementation project(':omnipod')
|
||||
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
implementation 'com.google.android.gms:play-services-wearable:17.0.0'
|
||||
|
|
|
@ -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
|
||||
|
@ -28,6 +30,7 @@ import javax.inject.Singleton
|
|||
WizardModule::class,
|
||||
RileyLinkModule::class,
|
||||
MedtronicModule::class,
|
||||
OmnipodModule::class,
|
||||
APSModule::class,
|
||||
PreferencesModule::class,
|
||||
OverviewModule::class,
|
||||
|
|
|
@ -34,6 +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.ui.OmnipodFragment
|
||||
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpFragment
|
||||
import info.nightscout.androidaps.plugins.source.BGSourceFragment
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsFragment
|
||||
|
@ -65,6 +66,7 @@ abstract class FragmentsModule {
|
|||
@ContributesAndroidInjector abstract fun contributesLoopFragment(): LoopFragment
|
||||
@ContributesAndroidInjector abstract fun contributesMaintenanceFragment(): MaintenanceFragment
|
||||
@ContributesAndroidInjector abstract fun contributesMedtronicFragment(): MedtronicFragment
|
||||
@ContributesAndroidInjector abstract fun contributesOmnipodFragment(): OmnipodFragment
|
||||
@ContributesAndroidInjector abstract fun contributesNSProfileFragment(): NSProfileFragment
|
||||
@ContributesAndroidInjector abstract fun contributesNSClientFragment(): NSClientFragment
|
||||
@ContributesAndroidInjector abstract fun contributesSmsCommunicatorFragment(): SmsCommunicatorFragment
|
||||
|
|
|
@ -40,6 +40,7 @@ import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin
|
|||
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.mdi.MDIPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodPumpPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
|
||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin
|
||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin
|
||||
|
@ -147,6 +148,12 @@ abstract class PluginsModule {
|
|||
@IntKey(150)
|
||||
abstract fun bindMedtronicPumpPlugin(plugin: MedtronicPumpPlugin): PluginBase
|
||||
|
||||
@Binds
|
||||
@PumpDriver
|
||||
@IntoMap
|
||||
@IntKey(155)
|
||||
abstract fun bindOmnipodPumpPlugin(plugin: OmnipodPumpPlugin): PluginBase
|
||||
|
||||
@Binds
|
||||
@NotNSClient
|
||||
@IntoMap
|
||||
|
|
|
@ -10,6 +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.rileylink.service.RileyLinkOmnipodService
|
||||
import info.nightscout.androidaps.services.AlarmSoundService
|
||||
import info.nightscout.androidaps.services.DataService
|
||||
import info.nightscout.androidaps.services.LocationService
|
||||
|
@ -29,4 +30,5 @@ abstract class ServicesModule {
|
|||
@ContributesAndroidInjector abstract fun contributesInsightConnectionService(): InsightConnectionService
|
||||
@ContributesAndroidInjector abstract fun contributesRileyLinkService(): RileyLinkService
|
||||
@ContributesAndroidInjector abstract fun contributesRileyLinkMedtronicService(): RileyLinkMedtronicService
|
||||
@ContributesAndroidInjector abstract fun contributesRileyLinkOmnipodService(): RileyLinkOmnipodService
|
||||
}
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -73,6 +73,7 @@ public class Notification {
|
|||
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";
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -21,6 +21,8 @@ import java.util.ArrayList;
|
|||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
@ -73,14 +75,18 @@ import info.nightscout.androidaps.plugins.pump.omnipod.definition.OmnipodCommand
|
|||
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;
|
||||
|
@ -107,6 +113,7 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
|
|||
private final AapsOmnipodManager aapsOmnipodManager;
|
||||
private final AapsOmnipodUtil aapsOmnipodUtil;
|
||||
private final RileyLinkUtil rileyLinkUtil;
|
||||
private final OmnipodAlertUtil omnipodAlertUtil;
|
||||
private final AAPSLogger aapsLogger;
|
||||
private final RxBusWrapper rxBus;
|
||||
private final ActivePluginProvider activePlugin;
|
||||
|
@ -154,7 +161,8 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
|
|||
ServiceTaskExecutor serviceTaskExecutor,
|
||||
DateUtil dateUtil,
|
||||
AapsOmnipodUtil aapsOmnipodUtil,
|
||||
RileyLinkUtil rileyLinkUtil
|
||||
RileyLinkUtil rileyLinkUtil,
|
||||
OmnipodAlertUtil omnipodAlertUtil
|
||||
) {
|
||||
super(new PluginDescription() //
|
||||
.mainType(PluginType.PUMP) //
|
||||
|
@ -178,6 +186,7 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
|
|||
this.aapsOmnipodManager = aapsOmnipodManager;
|
||||
this.aapsOmnipodUtil = aapsOmnipodUtil;
|
||||
this.rileyLinkUtil = rileyLinkUtil;
|
||||
this.omnipodAlertUtil = omnipodAlertUtil;
|
||||
|
||||
pumpDescription = new PumpDescription(pumpType);
|
||||
|
||||
|
@ -220,9 +229,13 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
|
|||
aapsOmnipodManager.createSuspendedFakeTbrIfNotExists();
|
||||
}
|
||||
|
||||
if (!OmnipodPumpPlugin.this.statusRequestList.isEmpty() || OmnipodPumpPlugin.this.hasTimeDateOrTimeZoneChanged) {
|
||||
if (!getCommandQueue().statusInQueue()) {
|
||||
getCommandQueue().readStatus(statusRequestList.isEmpty() ? "Date or Time Zone Changed" : "Status Refresh Requested", null);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -254,6 +267,11 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
|
|||
.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())
|
||||
|
@ -264,8 +282,16 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
|
|||
(event.isChanged(getResourceHelper(), R.string.key_omnipod_smb_beeps_enabled)) ||
|
||||
(event.isChanged(getResourceHelper(), R.string.key_omnipod_suspend_delivery_button_enabled)) ||
|
||||
(event.isChanged(getResourceHelper(), R.string.key_omnipod_pulse_log_button_enabled)) ||
|
||||
(event.isChanged(getResourceHelper(), R.string.key_omnipod_time_change_event_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)
|
||||
);
|
||||
disposables.add(rxBus
|
||||
|
@ -291,6 +317,17 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
|
|||
);
|
||||
}
|
||||
|
||||
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
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
|
@ -473,6 +510,32 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
|
|||
timeChangeRetries = 0;
|
||||
}
|
||||
}
|
||||
} else if (!verifyPodAlertConfiguration()) {
|
||||
Duration expirationReminderTimeBeforeShutdown = omnipodAlertUtil.getExpirationReminderTimeBeforeShutdown();
|
||||
Integer lowReservoirAlertUnits = omnipodAlertUtil.getLowReservoirAlertUnits();
|
||||
|
||||
List<AlertConfiguration> 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -483,19 +546,6 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
|
|||
|
||||
aapsLogger.info(LTag.PUMP, "Basal Profile was set: " + result.success);
|
||||
|
||||
if (result.success) {
|
||||
rxBus.send(new EventDismissNotification(Notification.OMNIPOD_POD_SUSPENDED));
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -890,7 +940,6 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
|
|||
|
||||
T pumpEnactResult = supplier.get();
|
||||
|
||||
// TODO maybe only do this for specific commands
|
||||
rxBus.send(new EventRefreshOverview("Omnipod command: " + commandType.name(), false));
|
||||
|
||||
rxBus.send(new EventOmnipodPumpValuesChanged());
|
||||
|
@ -898,6 +947,22 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface,
|
|||
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) {
|
||||
long currentCount = sp.getLong(statsKey, 0L);
|
||||
currentCount++;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -17,6 +17,7 @@ public enum OmnipodCommandType {
|
|||
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);
|
||||
|
|
|
@ -15,6 +15,10 @@ public class OmnipodStorageKeys {
|
|||
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 {
|
||||
|
|
|
@ -21,8 +21,8 @@ public enum PodHistoryEntryType {
|
|||
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),
|
||||
CANCEL_FAKE_SUSPENDED_TEMPORARY_BASAL(14, R.string.omnipod_cmd_cancel_fake_suspended_tbr),
|
||||
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),
|
||||
|
||||
|
|
|
@ -28,9 +28,17 @@ public class ConfigureAlertsAction implements OmnipodAction<StatusResponse> {
|
|||
public StatusResponse execute(OmnipodRileyLinkCommunicationManager 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());
|
||||
}
|
||||
updateConfiguredAlerts(podStateManager, alertConfigurations);
|
||||
return statusResponse;
|
||||
}
|
||||
|
||||
public static void updateConfiguredAlerts(PodStateManager podStateManager, List<AlertConfiguration> alertConfigurations) {
|
||||
for (AlertConfiguration alertConfiguration : alertConfigurations) {
|
||||
if (alertConfiguration.isActive()) {
|
||||
podStateManager.putConfiguredAlert(alertConfiguration.getAlertSlot(), alertConfiguration.getAlertType());
|
||||
} else {
|
||||
podStateManager.removeConfiguredAlert(alertConfiguration.getAlertSlot());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action;
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.service.InsertCannulaService;
|
||||
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;
|
||||
|
@ -12,22 +19,22 @@ import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.Omnipod
|
|||
public class InsertCannulaAction implements OmnipodAction<StatusResponse> {
|
||||
|
||||
private final PodStateManager podStateManager;
|
||||
private final InsertCannulaService service;
|
||||
private final BasalSchedule initialBasalSchedule;
|
||||
private final Duration expirationReminderTimeBeforeShutdown;
|
||||
private final Integer lowReservoirAlertUnits;
|
||||
|
||||
public InsertCannulaAction(InsertCannulaService insertCannulaService, PodStateManager podStateManager, BasalSchedule initialBasalSchedule) {
|
||||
if (insertCannulaService == null) {
|
||||
throw new ActionInitializationException("Insert cannula service cannot be null");
|
||||
}
|
||||
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.service = insertCannulaService;
|
||||
this.podStateManager = podStateManager;
|
||||
this.initialBasalSchedule = initialBasalSchedule;
|
||||
this.expirationReminderTimeBeforeShutdown = expirationReminderTimeBeforeShutdown;
|
||||
this.lowReservoirAlertUnits = lowReservoirAlertUnits;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -37,12 +44,19 @@ public class InsertCannulaAction implements OmnipodAction<StatusResponse> {
|
|||
}
|
||||
|
||||
if (podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.BASAL_INITIALIZED)) {
|
||||
service.programInitialBasalSchedule(communicationService, podStateManager, initialBasalSchedule);
|
||||
podStateManager.setBasalSchedule(initialBasalSchedule);
|
||||
communicationService.executeAction(new SetBasalScheduleAction(podStateManager, initialBasalSchedule,
|
||||
true, podStateManager.getScheduleOffset(), false));
|
||||
}
|
||||
|
||||
if (podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.INSERTING_CANNULA)) {
|
||||
service.executeExpirationRemindersAlertCommand(communicationService, podStateManager);
|
||||
return service.executeInsertionBolusCommand(communicationService, podStateManager);
|
||||
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));
|
||||
|
@ -50,4 +64,12 @@ public class InsertCannulaAction implements OmnipodAction<StatusResponse> {
|
|||
throw new IllegalPodProgressException(null, podStateManager.getPodProgressStatus());
|
||||
}
|
||||
}
|
||||
|
||||
private List<AlertConfiguration> 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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,8 +46,6 @@ public class SetBasalScheduleAction implements OmnipodAction<StatusResponse> {
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.Duration;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
@ -11,7 +10,6 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.mess
|
|||
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.definition.OmnipodConstants;
|
||||
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;
|
||||
|
@ -45,8 +43,6 @@ public class SetTempBasalAction implements OmnipodAction<StatusResponse> {
|
|||
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(OmnipodConstants.AVERAGE_TEMP_BASAL_COMMAND_COMMUNICATION_DURATION), rate, duration);
|
||||
return statusResponse;
|
||||
return communicationService.exchangeMessages(StatusResponse.class, podStateManager, message);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<AlertSlot, AlertConfiguration> 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<AlertConfiguration> build() {
|
||||
return new ArrayList<>(alerts.values());
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.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.driver.communication.action.BolusAction;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.ConfigureAlertsAction;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.SetBasalScheduleAction;
|
||||
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.schedule.BasalSchedule;
|
||||
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 InsertCannulaService {
|
||||
public StatusResponse programInitialBasalSchedule(OmnipodRileyLinkCommunicationManager communicationService,
|
||||
PodStateManager podStateManager, BasalSchedule basalSchedule) {
|
||||
return communicationService.executeAction(new SetBasalScheduleAction(podStateManager, basalSchedule,
|
||||
true, podStateManager.getScheduleOffset(), false));
|
||||
}
|
||||
|
||||
public StatusResponse executeExpirationRemindersAlertCommand(OmnipodRileyLinkCommunicationManager communicationService,
|
||||
PodStateManager podStateManager) {
|
||||
AlertConfiguration lowReservoirAlertConfiguration = AlertConfigurationUtil.createLowReservoirAlertConfiguration(OmnipodConstants.LOW_RESERVOIR_ALERT);
|
||||
|
||||
DateTime endOfServiceTime = podStateManager.getActivatedAt().plus(OmnipodConstants.SERVICE_DURATION);
|
||||
|
||||
Duration timeUntilExpirationAdvisoryAlarm = new Duration(DateTime.now(),
|
||||
endOfServiceTime.minus(OmnipodConstants.EXPIRATION_ADVISORY_WINDOW));
|
||||
Duration timeUntilShutdownImminentAlarm = new Duration(DateTime.now(),
|
||||
endOfServiceTime.minus(OmnipodConstants.END_OF_SERVICE_IMMINENT_WINDOW));
|
||||
|
||||
AlertConfiguration expirationAdvisoryAlertConfiguration = AlertConfigurationUtil.createExpirationAdvisoryAlertConfiguration(
|
||||
timeUntilExpirationAdvisoryAlarm, OmnipodConstants.EXPIRATION_ADVISORY_WINDOW);
|
||||
AlertConfiguration shutdownImminentAlertConfiguration = AlertConfigurationUtil.createShutdownImminentAlertConfiguration(
|
||||
timeUntilShutdownImminentAlarm);
|
||||
AlertConfiguration autoOffAlertConfiguration = AlertConfigurationUtil.createAutoOffAlertConfiguration(
|
||||
false, Duration.ZERO);
|
||||
|
||||
List<AlertConfiguration> alertConfigurations = Arrays.asList( //
|
||||
lowReservoirAlertConfiguration, //
|
||||
expirationAdvisoryAlertConfiguration, //
|
||||
shutdownImminentAlertConfiguration, //
|
||||
autoOffAlertConfiguration //
|
||||
);
|
||||
|
||||
return communicationService.executeAction(new ConfigureAlertsAction(podStateManager, alertConfigurations));
|
||||
}
|
||||
|
||||
public StatusResponse executeInsertionBolusCommand(OmnipodRileyLinkCommunicationManager communicationService, PodStateManager podStateManager) {
|
||||
return communicationService.executeAction(new BolusAction(podStateManager, OmnipodConstants.POD_CANNULA_INSERTION_BOLUS_UNITS,
|
||||
Duration.standardSeconds(1), false, false));
|
||||
}
|
||||
}
|
|
@ -21,8 +21,8 @@ public class PodInfoResponse extends MessageBlock {
|
|||
return subType;
|
||||
}
|
||||
|
||||
public <T extends PodInfo> T getPodInfo() {
|
||||
return (T) podInfo;
|
||||
public PodInfo getPodInfo() {
|
||||
return podInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -15,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;
|
||||
|
@ -35,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;
|
||||
|
@ -67,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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition;
|
||||
|
||||
abstract class AlertTrigger<T> {
|
||||
public abstract class AlertTrigger<T> {
|
||||
private final T value;
|
||||
|
||||
AlertTrigger(T value) {
|
||||
|
@ -10,4 +10,10 @@ abstract class AlertTrigger<T> {
|
|||
public T getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
return "AlertTrigger{" +
|
||||
"value=" + value +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ 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;
|
||||
|
@ -16,6 +17,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.acti
|
|||
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;
|
||||
|
@ -24,12 +26,12 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.acti
|
|||
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.InsertCannulaService;
|
||||
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;
|
||||
|
@ -131,7 +133,8 @@ public class OmnipodManager {
|
|||
.observeOn(Schedulers.io());
|
||||
}
|
||||
|
||||
public synchronized Single<SetupActionResult> insertCannula(BasalSchedule basalSchedule) {
|
||||
public synchronized Single<SetupActionResult> 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());
|
||||
}
|
||||
|
@ -146,7 +149,7 @@ 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");
|
||||
}
|
||||
|
@ -184,6 +187,18 @@ public class OmnipodManager {
|
|||
}
|
||||
}
|
||||
|
||||
public synchronized StatusResponse configureAlerts(List<AlertConfiguration> 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();
|
||||
|
||||
|
@ -209,6 +224,10 @@ public class OmnipodManager {
|
|||
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 {
|
||||
executeAndVerify(() -> communicationService.executeAction(new SetBasalScheduleAction(podStateManager, schedule,
|
||||
false, podStateManager.getScheduleOffset(), acknowledgementBeep)));
|
||||
|
@ -240,7 +259,7 @@ public class OmnipodManager {
|
|||
|
||||
logStartingCommandExecution("setTemporaryBasal [rate=" + rate + ", duration=" + duration + ", acknowledgementBeep=" + acknowledgementBeep + ", completionBeep=" + completionBeep + "]");
|
||||
|
||||
boolean cancelCurrentTbr = podStateManager.getLastDeliveryStatus().isTbrRunning();
|
||||
boolean cancelCurrentTbr = podStateManager.isTempBasalRunning();
|
||||
|
||||
try {
|
||||
if (cancelCurrentTbr) {
|
||||
|
@ -262,6 +281,7 @@ public class OmnipodManager {
|
|||
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) {
|
||||
|
@ -271,13 +291,28 @@ public class OmnipodManager {
|
|||
}
|
||||
|
||||
// verifyDeliveryStatus will throw an exception if verification fails
|
||||
if (!verifyDeliveryStatus(DeliveryStatus.TEMP_BASAL_RUNNING, ex)) {
|
||||
if (cancelCurrentTbr) {
|
||||
throw new CommandFailedAfterChangingDeliveryStatusException("Failed to set new TBR while cancelling old TBR succeeded", ex);
|
||||
}
|
||||
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;
|
||||
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 {
|
||||
|
@ -331,14 +366,16 @@ public class OmnipodManager {
|
|||
commandDeliveryStatus = CommandDeliveryStatus.UNCERTAIN_FAILURE;
|
||||
}
|
||||
|
||||
DateTime startDate = DateTime.now().minus(OmnipodConstants.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, OmnipodConstants.POD_BOLUS_DELIVERY_RATE);
|
||||
Duration estimatedRemainingBolusDuration = bolusDuration.minus(OmnipodConstants.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;
|
||||
|
||||
|
@ -354,7 +391,7 @@ public class OmnipodManager {
|
|||
SingleSubject<BolusDeliveryResult> 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
|
||||
|
@ -379,7 +416,7 @@ public class OmnipodManager {
|
|||
break;
|
||||
}
|
||||
} catch (PodFaultException ex) {
|
||||
// Substract units not delivered in case of a Pod failure
|
||||
// Subtract units not delivered in case of a Pod failure
|
||||
bolusNotDelivered = ex.getFaultEvent().getBolusNotDelivered();
|
||||
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "Caught PodFaultException in bolus completion verification", ex);
|
||||
|
@ -427,7 +464,7 @@ public class OmnipodManager {
|
|||
private void discardActiveBolusData(double bolusNotDelivered) {
|
||||
synchronized (bolusDataMutex) {
|
||||
double unitsDelivered = activeBolusData.getUnits() - bolusNotDelivered;
|
||||
podStateManager.setLastBolus(activeBolusData.getStartDate(), unitsDelivered);
|
||||
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;
|
||||
|
@ -464,8 +501,6 @@ public class OmnipodManager {
|
|||
logStartingCommandExecution("setTime [acknowledgementBeeps=" + acknowledgementBeeps + "]");
|
||||
|
||||
try {
|
||||
suspendDelivery(acknowledgementBeeps);
|
||||
|
||||
DateTimeZone oldTimeZone = podStateManager.getTimeZone();
|
||||
|
||||
try {
|
||||
|
@ -475,20 +510,8 @@ public class OmnipodManager {
|
|||
|
||||
setBasalSchedule(podStateManager.getBasalSchedule(), acknowledgementBeeps);
|
||||
} catch (OmnipodException ex) {
|
||||
if (ex.isCertainFailure()) {
|
||||
podStateManager.setTimeZone(oldTimeZone);
|
||||
throw new CommandFailedAfterChangingDeliveryStatusException("Suspending delivery succeeded but resuming did not", ex);
|
||||
}
|
||||
|
||||
try {
|
||||
// verifyDeliveryStatus will throw an exception if verification fails
|
||||
if (!verifyDeliveryStatus(DeliveryStatus.NORMAL, ex)) {
|
||||
throw new CommandFailedAfterChangingDeliveryStatusException("Suspending delivery succeeded but resuming did not", ex);
|
||||
}
|
||||
} catch (Exception ex2) {
|
||||
podStateManager.setTimeZone(oldTimeZone);
|
||||
throw ex2;
|
||||
}
|
||||
podStateManager.setTimeZone(oldTimeZone);
|
||||
throw ex;
|
||||
}
|
||||
} finally {
|
||||
logCommandExecutionFinished("setTime");
|
||||
|
@ -505,7 +528,7 @@ public class OmnipodManager {
|
|||
// Try to get pulse log for diagnostics
|
||||
try {
|
||||
PodInfoResponse podInfoResponse = communicationService.executeAction(new GetPodInfoAction(podStateManager, PodInfoType.RECENT_PULSE_LOG));
|
||||
PodInfoRecentPulseLog pulseLogInfo = podInfoResponse.getPodInfo();
|
||||
PodInfoRecentPulseLog pulseLogInfo = (PodInfoRecentPulseLog) podInfoResponse.getPodInfo();
|
||||
aapsLogger.info(LTag.PUMPCOMM, "Retrieved pulse log from the pod: {}", pulseLogInfo.toString());
|
||||
} catch (Exception ex) {
|
||||
aapsLogger.warn(LTag.PUMPCOMM, "Failed to retrieve pulse log from the pod", ex);
|
||||
|
@ -619,13 +642,14 @@ public class OmnipodManager {
|
|||
*/
|
||||
private boolean verifyDeliveryStatus(DeliveryStatus expectedStatus, Throwable verificationCause) {
|
||||
aapsLogger.debug(LTag.PUMPCOMM, "Attempting to verify delivery status (expected={})", expectedStatus);
|
||||
for (int i = 0; 2 > i; i++) {
|
||||
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 ignored) {
|
||||
// ignore and try to continue
|
||||
} 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");
|
||||
|
@ -693,12 +717,14 @@ public class OmnipodManager {
|
|||
private static class ActiveBolusData {
|
||||
private final double units;
|
||||
private final DateTime startDate;
|
||||
private final CommandDeliveryStatus commandDeliveryStatus;
|
||||
private final SingleSubject<BolusDeliveryResult> bolusCompletionSubject;
|
||||
private final CompositeDisposable disposables;
|
||||
|
||||
private ActiveBolusData(double units, DateTime startDate, SingleSubject<BolusDeliveryResult> bolusCompletionSubject, CompositeDisposable disposables) {
|
||||
private ActiveBolusData(double units, DateTime startDate, CommandDeliveryStatus commandDeliveryStatus, SingleSubject<BolusDeliveryResult> bolusCompletionSubject, CompositeDisposable disposables) {
|
||||
this.units = units;
|
||||
this.startDate = startDate;
|
||||
this.commandDeliveryStatus = commandDeliveryStatus;
|
||||
this.bolusCompletionSubject = bolusCompletionSubject;
|
||||
this.disposables = disposables;
|
||||
}
|
||||
|
@ -711,6 +737,10 @@ public class OmnipodManager {
|
|||
return startDate;
|
||||
}
|
||||
|
||||
CommandDeliveryStatus getCommandDeliveryStatus() {
|
||||
return commandDeliveryStatus;
|
||||
}
|
||||
|
||||
CompositeDisposable getDisposables() {
|
||||
return disposables;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ 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;
|
||||
|
@ -352,37 +353,110 @@ 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 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
|
||||
*/
|
||||
|
@ -404,15 +478,23 @@ public abstract class PodStateManager {
|
|||
podState.setReservoirLevel(statusResponse.getReservoirLevel());
|
||||
podState.setTotalTicksDelivered(statusResponse.getTicksDelivered());
|
||||
podState.setPodProgressStatus(statusResponse.getPodProgressStatus());
|
||||
if (!statusResponse.getDeliveryStatus().isTbrRunning()) {
|
||||
podState.setLastTempBasalStartTime(null);
|
||||
podState.setLastTempBasalAmount(null);
|
||||
podState.setLastTempBasalDuration(null);
|
||||
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());
|
||||
});
|
||||
}
|
||||
|
||||
protected void onTbrChanged() {
|
||||
// Deliberately left empty
|
||||
// Can be overridden in subclasses
|
||||
}
|
||||
|
||||
private void setAndStore(Runnable runnable) {
|
||||
setSafe(runnable);
|
||||
storePodState();
|
||||
|
@ -507,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<AlertSlot, AlertType> configuredAlerts = new HashMap<>();
|
||||
|
||||
private PodState(int address) {
|
||||
|
@ -712,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<AlertSlot, AlertType> 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 +
|
||||
|
@ -766,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 +
|
||||
'}';
|
||||
}
|
||||
|
|
|
@ -11,19 +11,19 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.TimerAl
|
|||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.UnitsRemainingAlertTrigger;
|
||||
|
||||
public class AlertConfigurationUtil {
|
||||
public static AlertConfiguration createLowReservoirAlertConfiguration(Double units) {
|
||||
return new AlertConfiguration(AlertType.LOW_RESERVOIR_ALERT, AlertSlot.SLOT4, true, false, Duration.ZERO,
|
||||
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) {
|
||||
|
|
|
@ -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()
|
|
@ -1,7 +1,6 @@
|
|||
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;
|
||||
|
@ -44,6 +41,8 @@ import info.nightscout.androidaps.plugins.pump.omnipod.definition.PodInitReceive
|
|||
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;
|
||||
|
@ -75,6 +74,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.SetupActio
|
|||
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;
|
||||
|
@ -94,6 +94,7 @@ public class AapsOmnipodManager {
|
|||
private final SP sp;
|
||||
private final OmnipodManager delegate;
|
||||
private final DatabaseHelperInterface databaseHelper;
|
||||
private final OmnipodAlertUtil omnipodAlertUtil;
|
||||
|
||||
private boolean basalBeepsEnabled;
|
||||
private boolean bolusBeepsEnabled;
|
||||
|
@ -114,7 +115,8 @@ public class AapsOmnipodManager {
|
|||
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");
|
||||
}
|
||||
|
@ -128,6 +130,7 @@ public class AapsOmnipodManager {
|
|||
this.context = context;
|
||||
this.databaseHelper = databaseHelper;
|
||||
this.sp = sp;
|
||||
this.omnipodAlertUtil = omnipodAlertUtil;
|
||||
|
||||
delegate = new OmnipodManager(aapsLogger, sp, communicationService, podStateManager);
|
||||
}
|
||||
|
@ -153,17 +156,15 @@ public class AapsOmnipodManager {
|
|||
return new PumpEnactResult(injector).success(false).enacted(false).comment(getStringResource(R.string.omnipod_error_illegal_init_action_type, podInitActionType.name()));
|
||||
}
|
||||
|
||||
long time = System.currentTimeMillis();
|
||||
|
||||
try {
|
||||
Disposable disposable = delegate.pairAndPrime().subscribe(res -> //
|
||||
handleSetupActionResult(podInitActionType, podInitReceiver, res, time, null));
|
||||
handleSetupActionResult(podInitActionType, podInitReceiver, res, System.currentTimeMillis(), null));
|
||||
|
||||
return new PumpEnactResult(injector).success(true).enacted(true);
|
||||
} catch (Exception ex) {
|
||||
String comment = handleAndTranslateException(ex);
|
||||
podInitReceiver.returnInitTaskStatus(podInitActionType, false, comment);
|
||||
addFailureToHistory(time, PodHistoryEntryType.PAIR_AND_PRIME, comment);
|
||||
addFailureToHistory(System.currentTimeMillis(), PodHistoryEntryType.PAIR_AND_PRIME, comment);
|
||||
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
|
||||
}
|
||||
}
|
||||
|
@ -173,8 +174,6 @@ public class AapsOmnipodManager {
|
|||
return new PumpEnactResult(injector).success(false).enacted(false).comment(getStringResource(R.string.omnipod_error_illegal_init_action_type, podInitActionType.name()));
|
||||
}
|
||||
|
||||
long time = System.currentTimeMillis();
|
||||
|
||||
try {
|
||||
BasalSchedule basalSchedule;
|
||||
try {
|
||||
|
@ -182,8 +181,9 @@ public class AapsOmnipodManager {
|
|||
} catch (Exception ex) {
|
||||
throw new CommandInitializationException("Basal profile mapping failed", ex);
|
||||
}
|
||||
Disposable disposable = delegate.insertCannula(basalSchedule).subscribe(res -> //
|
||||
handleSetupActionResult(podInitActionType, podInitReceiver, res, time, profile));
|
||||
|
||||
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));
|
||||
|
||||
|
@ -193,36 +193,46 @@ public class AapsOmnipodManager {
|
|||
} catch (Exception ex) {
|
||||
String comment = handleAndTranslateException(ex);
|
||||
podInitReceiver.returnInitTaskStatus(podInitActionType, false, comment);
|
||||
addFailureToHistory(time, PodHistoryEntryType.FILL_CANNULA_SET_BASAL_PROFILE, comment);
|
||||
addFailureToHistory(PodHistoryEntryType.FILL_CANNULA_SET_BASAL_PROFILE, comment);
|
||||
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
|
||||
}
|
||||
}
|
||||
|
||||
public PumpEnactResult configureAlerts(List<AlertConfiguration> 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() {
|
||||
long time = System.currentTimeMillis();
|
||||
try {
|
||||
StatusResponse statusResponse = delegate.getPodStatus();
|
||||
addSuccessToHistory(time, PodHistoryEntryType.GET_POD_STATUS, statusResponse);
|
||||
addSuccessToHistory(PodHistoryEntryType.GET_POD_STATUS, statusResponse);
|
||||
return new PumpEnactResult(injector).success(true).enacted(false);
|
||||
} catch (Exception ex) {
|
||||
String comment = handleAndTranslateException(ex);
|
||||
addFailureToHistory(time, PodHistoryEntryType.GET_POD_STATUS, comment);
|
||||
addFailureToHistory(PodHistoryEntryType.GET_POD_STATUS, comment);
|
||||
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
|
||||
}
|
||||
}
|
||||
|
||||
public PumpEnactResult deactivatePod(PodInitReceiver podInitReceiver) {
|
||||
long time = System.currentTimeMillis();
|
||||
try {
|
||||
delegate.deactivatePod();
|
||||
} catch (Exception ex) {
|
||||
String comment = handleAndTranslateException(ex);
|
||||
podInitReceiver.returnInitTaskStatus(PodInitActionType.DEACTIVATE_POD_WIZARD_STEP, false, comment);
|
||||
addFailureToHistory(time, PodHistoryEntryType.DEACTIVATE_POD, comment);
|
||||
addFailureToHistory(PodHistoryEntryType.DEACTIVATE_POD, comment);
|
||||
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
|
||||
}
|
||||
|
||||
addSuccessToHistory(time, PodHistoryEntryType.DEACTIVATE_POD, null);
|
||||
addSuccessToHistory(PodHistoryEntryType.DEACTIVATE_POD, null);
|
||||
|
||||
createSuspendedFakeTbrIfNotExists();
|
||||
|
||||
|
@ -232,7 +242,6 @@ public class AapsOmnipodManager {
|
|||
}
|
||||
|
||||
public PumpEnactResult setBasalProfile(Profile profile) {
|
||||
long time = System.currentTimeMillis();
|
||||
PodHistoryEntryType historyEntryType = podStateManager.isSuspended() ? PodHistoryEntryType.RESUME_DELIVERY : PodHistoryEntryType.SET_BASAL_SCHEDULE;
|
||||
|
||||
try {
|
||||
|
@ -244,31 +253,40 @@ public class AapsOmnipodManager {
|
|||
}
|
||||
delegate.setBasalSchedule(basalSchedule, isBasalBeepsEnabled());
|
||||
|
||||
time = System.currentTimeMillis();
|
||||
// Because setting a basal profile actually suspends and then resumes delivery, TBR is implicitly cancelled
|
||||
if (historyEntryType == PodHistoryEntryType.RESUME_DELIVERY) {
|
||||
cancelSuspendedFakeTbrIfExists();
|
||||
} else {
|
||||
reportImplicitlyCancelledTbr(time - 1000);
|
||||
}
|
||||
addSuccessToHistory(time, historyEntryType, profile.getBasalValues());
|
||||
addSuccessToHistory(historyEntryType, profile.getBasalValues());
|
||||
} catch (CommandFailedAfterChangingDeliveryStatusException ex) {
|
||||
createSuspendedFakeTbrIfNotExists();
|
||||
String comment = getStringResource(R.string.omnipod_error_set_basal_failed_delivery_suspended);
|
||||
showErrorDialog(comment, R.raw.boluserror);
|
||||
addFailureToHistory(time, historyEntryType, 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);
|
||||
} catch (DeliveryStatusVerificationFailedException ex) {
|
||||
String comment = getStringResource(R.string.omnipod_error_set_basal_failed_delivery_might_be_suspended);
|
||||
showErrorDialog(comment, R.raw.boluserror);
|
||||
addFailureToHistory(time, historyEntryType, comment);
|
||||
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);
|
||||
addFailureToHistory(time, historyEntryType, 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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -306,8 +324,11 @@ public class AapsOmnipodManager {
|
|||
|
||||
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();
|
||||
|
@ -382,7 +403,7 @@ public class AapsOmnipodManager {
|
|||
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());
|
||||
showPodFaultNotification(ex.getFaultEvent().getFaultEventCode());
|
||||
addSuccessToHistory(System.currentTimeMillis(), PodHistoryEntryType.CANCEL_BOLUS, null);
|
||||
return new PumpEnactResult(injector).success(true).enacted(true);
|
||||
} catch (Exception ex) {
|
||||
|
@ -397,48 +418,56 @@ public class AapsOmnipodManager {
|
|||
|
||||
public PumpEnactResult setTemporaryBasal(TempBasalPair tempBasalPair) {
|
||||
boolean beepsEnabled = isTbrBeepsEnabled();
|
||||
long time = System.currentTimeMillis();
|
||||
try {
|
||||
delegate.setTemporaryBasal(PumpType.Insulet_Omnipod.determineCorrectBasalSize(tempBasalPair.getInsulinRate()), Duration.standardMinutes(tempBasalPair.getDurationMinutes()), beepsEnabled, beepsEnabled);
|
||||
time = System.currentTimeMillis();
|
||||
} catch (CommandFailedAfterChangingDeliveryStatusException ex) {
|
||||
reportImplicitlyCancelledTbr(time);
|
||||
String comment = getStringResource(R.string.omnipod_cancelled_old_tbr_failed_to_set_new);
|
||||
addFailureToHistory(time, PodHistoryEntryType.SET_TEMPORARY_BASAL, comment);
|
||||
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 = getStringResource(R.string.omnipod_error_set_temp_basal_failed_old_tbr_might_be_cancelled);
|
||||
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);
|
||||
}
|
||||
|
||||
showNotification(comment, Notification.URGENT, R.raw.boluserror);
|
||||
addFailureToHistory(time, PodHistoryEntryType.SET_TEMPORARY_BASAL, comment);
|
||||
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
|
||||
} catch (Exception ex) {
|
||||
String comment = handleAndTranslateException(ex);
|
||||
addFailureToHistory(time, PodHistoryEntryType.SET_TEMPORARY_BASAL, comment);
|
||||
addFailureToHistory(PodHistoryEntryType.SET_TEMPORARY_BASAL, comment);
|
||||
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
|
||||
}
|
||||
|
||||
long pumpId = addSuccessToHistory(time, PodHistoryEntryType.SET_TEMPORARY_BASAL, tempBasalPair);
|
||||
long pumpId = addSuccessToHistory(PodHistoryEntryType.SET_TEMPORARY_BASAL, tempBasalPair);
|
||||
|
||||
TemporaryBasal tempStart = new TemporaryBasal(injector) //
|
||||
.date(time) //
|
||||
.duration(tempBasalPair.getDurationMinutes()) //
|
||||
.absolute(tempBasalPair.getInsulinRate()) //
|
||||
.pumpId(pumpId)
|
||||
.source(Source.PUMP);
|
||||
|
||||
activePlugin.getActiveTreatments().addToHistoryTempBasal(tempStart);
|
||||
addTempBasalTreatment(System.currentTimeMillis(), pumpId, tempBasalPair);
|
||||
|
||||
return new PumpEnactResult(injector).success(true).enacted(true);
|
||||
}
|
||||
|
||||
public PumpEnactResult cancelTemporaryBasal() {
|
||||
long time = System.currentTimeMillis();
|
||||
try {
|
||||
delegate.cancelTemporaryBasal(isTbrBeepsEnabled());
|
||||
addSuccessToHistory(time, PodHistoryEntryType.CANCEL_TEMPORARY_BASAL, null);
|
||||
addSuccessToHistory(PodHistoryEntryType.CANCEL_TEMPORARY_BASAL, null);
|
||||
} catch (Exception ex) {
|
||||
String comment = handleAndTranslateException(ex);
|
||||
addFailureToHistory(time, PodHistoryEntryType.CANCEL_TEMPORARY_BASAL, comment);
|
||||
addFailureToHistory(PodHistoryEntryType.CANCEL_TEMPORARY_BASAL, comment);
|
||||
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
|
||||
}
|
||||
|
||||
|
@ -446,30 +475,27 @@ public class AapsOmnipodManager {
|
|||
}
|
||||
|
||||
public PumpEnactResult acknowledgeAlerts() {
|
||||
long time = System.currentTimeMillis();
|
||||
try {
|
||||
delegate.acknowledgeAlerts();
|
||||
addSuccessToHistory(time, PodHistoryEntryType.ACKNOWLEDGE_ALERTS, null);
|
||||
addSuccessToHistory(PodHistoryEntryType.ACKNOWLEDGE_ALERTS, null);
|
||||
} catch (Exception ex) {
|
||||
String comment = handleAndTranslateException(ex);
|
||||
addFailureToHistory(time, PodHistoryEntryType.ACKNOWLEDGE_ALERTS, comment);
|
||||
addFailureToHistory(PodHistoryEntryType.ACKNOWLEDGE_ALERTS, comment);
|
||||
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
|
||||
}
|
||||
return new PumpEnactResult(injector).success(true).enacted(true);
|
||||
}
|
||||
|
||||
public PumpEnactResult suspendDelivery() {
|
||||
long time = System.currentTimeMillis();
|
||||
|
||||
try {
|
||||
delegate.suspendDelivery(isBasalBeepsEnabled());
|
||||
} catch (Exception ex) {
|
||||
String comment = handleAndTranslateException(ex);
|
||||
addFailureToHistory(time, PodHistoryEntryType.SUSPEND_DELIVERY, comment);
|
||||
addFailureToHistory(PodHistoryEntryType.SUSPEND_DELIVERY, comment);
|
||||
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
|
||||
}
|
||||
|
||||
addSuccessToHistory(time, PodHistoryEntryType.SUSPEND_DELIVERY, null);
|
||||
addSuccessToHistory(PodHistoryEntryType.SUSPEND_DELIVERY, null);
|
||||
|
||||
createSuspendedFakeTbrIfNotExists();
|
||||
|
||||
|
@ -478,27 +504,23 @@ public class AapsOmnipodManager {
|
|||
|
||||
// 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());
|
||||
time = System.currentTimeMillis();
|
||||
// Because set time actually suspends and then resumes delivery, TBR is implicitly cancelled
|
||||
reportImplicitlyCancelledTbr(time - 1000);
|
||||
addSuccessToHistory(time, PodHistoryEntryType.SET_TIME, null);
|
||||
addSuccessToHistory(PodHistoryEntryType.SET_TIME, null);
|
||||
} catch (CommandFailedAfterChangingDeliveryStatusException ex) {
|
||||
createSuspendedFakeTbrIfNotExists();
|
||||
String comment = getStringResource(R.string.omnipod_error_set_time_failed_delivery_suspended);
|
||||
showErrorDialog(comment, R.raw.boluserror);
|
||||
addFailureToHistory(time, PodHistoryEntryType.SET_TIME, comment);
|
||||
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);
|
||||
showErrorDialog(comment, R.raw.boluserror);
|
||||
addFailureToHistory(time, PodHistoryEntryType.SET_TIME, comment);
|
||||
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) {
|
||||
String comment = handleAndTranslateException(ex);
|
||||
addFailureToHistory(time, PodHistoryEntryType.SET_TIME, comment);
|
||||
addFailureToHistory(PodHistoryEntryType.SET_TIME, comment);
|
||||
return new PumpEnactResult(injector).success(false).enacted(false).comment(comment);
|
||||
}
|
||||
|
||||
|
@ -507,7 +529,7 @@ public class AapsOmnipodManager {
|
|||
|
||||
public PodInfoRecentPulseLog readPulseLog() {
|
||||
PodInfoResponse response = delegate.getPodInfo(PodInfoType.RECENT_PULSE_LOG);
|
||||
return response.getPodInfo();
|
||||
return (PodInfoRecentPulseLog) response.getPodInfo();
|
||||
}
|
||||
|
||||
public OmnipodRileyLinkCommunicationManager getCommunicationService() {
|
||||
|
@ -593,27 +615,43 @@ public class AapsOmnipodManager {
|
|||
return false;
|
||||
}
|
||||
|
||||
private void reportImplicitlyCancelledTbr(long time) {
|
||||
TreatmentsInterface plugin = activePlugin.getActiveTreatments();
|
||||
if (plugin.isTempBasalInProgress()) {
|
||||
aapsLogger.debug(LTag.PUMP, "Reporting implicitly cancelled TBR to Treatments plugin");
|
||||
public void reportCancelledTbr() {
|
||||
aapsLogger.debug(LTag.PUMP, "Reporting cancelled TBR to AAPS");
|
||||
|
||||
long pumpId = addSuccessToHistory(time, PodHistoryEntryType.CANCEL_TEMPORARY_BASAL_BY_DRIVER, null);
|
||||
long pumpId = addSuccessToHistory(PodHistoryEntryType.CANCEL_TEMPORARY_BASAL_BY_DRIVER, null);
|
||||
|
||||
TemporaryBasal temporaryBasal = new TemporaryBasal(injector) //
|
||||
.date(time) //
|
||||
.duration(0) //
|
||||
.source(Source.PUMP) //
|
||||
.pumpId(pumpId);
|
||||
TemporaryBasal temporaryBasal = new TemporaryBasal(injector) //
|
||||
.date(System.currentTimeMillis()) //
|
||||
.duration(0) //
|
||||
.source(Source.PUMP) //
|
||||
.pumpId(pumpId);
|
||||
|
||||
plugin.addToHistoryTempBasal(temporaryBasal);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
@ -697,7 +735,7 @@ public class AapsOmnipodManager {
|
|||
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);
|
||||
|
@ -725,26 +763,21 @@ public class AapsOmnipodManager {
|
|||
rxBus.send(event);
|
||||
}
|
||||
|
||||
private void showPodFaultErrorDialog(FaultEventCode faultEventCode) {
|
||||
showPodFaultErrorDialog(faultEventCode, R.raw.boluserror);
|
||||
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, 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) {
|
||||
|
|
|
@ -4,18 +4,22 @@ 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) {
|
||||
public AapsPodStateManager(AAPSLogger aapsLogger, SP sp, RxBusWrapper rxBus) {
|
||||
super(aapsLogger);
|
||||
this.sp = sp;
|
||||
this.rxBus = rxBus;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -27,4 +31,8 @@ public class AapsPodStateManager extends PodStateManager {
|
|||
protected void storePodState(String podState) {
|
||||
sp.putString(OmnipodStorageKeys.Preferences.POD_STATE, podState);
|
||||
}
|
||||
|
||||
@Override protected void onTbrChanged() {
|
||||
rxBus.send(new EventOmnipodTbrChanged());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.mess
|
|||
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;
|
||||
|
@ -127,6 +128,11 @@ public class OmnipodRileyLinkCommunicationManager extends RileyLinkCommunication
|
|||
|
||||
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)) {
|
||||
|
@ -150,9 +156,10 @@ public class OmnipodRileyLinkCommunicationManager extends RileyLinkCommunication
|
|||
throw new PodReturnedErrorResponseException(error);
|
||||
}
|
||||
} else if (responseMessageBlock.getType() == MessageBlockType.POD_INFO_RESPONSE && ((PodInfoResponse) responseMessageBlock).getSubType() == PodInfoType.FAULT_EVENT) {
|
||||
PodInfoFaultEvent faultEvent = ((PodInfoResponse) responseMessageBlock).getPodInfo();
|
||||
PodInfoFaultEvent faultEvent = (PodInfoFaultEvent) ((PodInfoResponse) responseMessageBlock).getPodInfo();
|
||||
podStateManager.setFaultEvent(faultEvent);
|
||||
podStateManager.setLastFailedCommunication(DateTime.now());
|
||||
// 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());
|
||||
|
|
|
@ -205,6 +205,8 @@ class OmnipodFragment : DaggerFragment() {
|
|||
|
||||
private fun updateOmnipodStatus() {
|
||||
updateLastConnection()
|
||||
updateLastBolus()
|
||||
updateTempBasal()
|
||||
updatePodStatus()
|
||||
|
||||
val errors = ArrayList<String>();
|
||||
|
@ -225,11 +227,10 @@ class OmnipodFragment : DaggerFragment() {
|
|||
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_temp_basal.text = PLACEHOLDER
|
||||
omnipod_last_bolus.text = PLACEHOLDER
|
||||
omnipod_pod_active_alerts.text = PLACEHOLDER
|
||||
} else {
|
||||
omnipod_pod_address.text = podStateManager.address.toString()
|
||||
|
@ -237,10 +238,16 @@ class OmnipodFragment : DaggerFragment() {
|
|||
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) {
|
||||
PLACEHOLDER
|
||||
if (expiresAt == null) {
|
||||
omnipod_pod_expiry.text = PLACEHOLDER
|
||||
omnipod_pod_expiry.setTextColor(Color.WHITE)
|
||||
} else {
|
||||
dateUtil.dateAndTimeString(expiresAt.toDate())
|
||||
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()) {
|
||||
|
@ -248,13 +255,6 @@ class OmnipodFragment : DaggerFragment() {
|
|||
errors.add(resourceHelper.gs(R.string.omnipod_pod_status_pod_fault_description, faultEventCode.value, faultEventCode.name))
|
||||
}
|
||||
|
||||
// last bolus
|
||||
omnipod_last_bolus.text = if (podStateManager.lastBolusStartTime != null && podStateManager.lastBolusAmount != null) {
|
||||
resourceHelper.gs(R.string.omnipod_last_bolus, omnipodPumpPlugin.model().determineCorrectBolusSize(podStateManager.lastBolusAmount), resourceHelper.gs(R.string.insulin_unit_shortname), readableDuration(podStateManager.lastBolusStartTime))
|
||||
} else {
|
||||
PLACEHOLDER
|
||||
}
|
||||
|
||||
val now = DateTime.now()
|
||||
|
||||
// base basal rate
|
||||
|
@ -264,22 +264,6 @@ class OmnipodFragment : DaggerFragment() {
|
|||
PLACEHOLDER
|
||||
}
|
||||
|
||||
// Temp basal
|
||||
val lastTempBasalStartTime = podStateManager.lastTempBasalStartTime;
|
||||
val lastTempBasalAmount = podStateManager.lastTempBasalAmount
|
||||
val lastTempBasalDuration = podStateManager.lastTempBasalDuration;
|
||||
if (lastTempBasalStartTime != null && lastTempBasalAmount != null && lastTempBasalDuration != null) {
|
||||
val endTime = lastTempBasalStartTime.plus(lastTempBasalDuration);
|
||||
val minutesRunning = Duration(lastTempBasalStartTime, now).standardMinutes
|
||||
omnipod_temp_basal.text = if (endTime.isAfter(now)) {
|
||||
resourceHelper.gs(R.string.omnipod_temp_basal, lastTempBasalAmount, dateUtil.timeString(lastTempBasalStartTime.millis), minutesRunning, lastTempBasalDuration.standardMinutes)
|
||||
} else {
|
||||
PLACEHOLDER
|
||||
}
|
||||
} else {
|
||||
omnipod_temp_basal.text = 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);
|
||||
|
@ -371,6 +355,55 @@ class OmnipodFragment : DaggerFragment() {
|
|||
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
|
||||
|
|
|
@ -12,6 +12,7 @@ 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;
|
||||
|
@ -27,14 +28,17 @@ import info.nightscout.androidaps.utils.sharedPreferences.SP;
|
|||
public class InitPodRefreshAction extends AbstractCancelAction implements FinishActionInterface {
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -50,6 +54,8 @@ public class InitPodRefreshAction extends AbstractCancelAction implements Finish
|
|||
public void execute() {
|
||||
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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
12
omnipod/src/main/res/drawable/ic_exit_to_app.xml
Normal file
12
omnipod/src/main/res/drawable/ic_exit_to_app.xml
Normal file
|
@ -0,0 +1,12 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M16.495,12.092l-4.921,-4.92l-1.444,1.444l2.468,2.467l-9.765,0l0,2.042l9.765,0l-2.468,2.467l1.444,1.444l4.921,-4.92l-0.012,-0.012z"
|
||||
android:fillColor="@color/white"/>
|
||||
<path
|
||||
android:pathData="M18.682,2.975H5.152c-1.272,0 -2.307,1.035 -2.307,2.307v3.801h2.126V5.282c0,-0.1 0.081,-0.181 0.181,-0.181h13.53c0.1,0 0.181,0.081 0.181,0.181v13.436c0,0.1 -0.081,0.181 -0.181,0.181H5.152c-0.1,0 -0.181,-0.081 -0.181,-0.181v-3.593H2.845v3.593c0,1.272 1.035,2.307 2.307,2.307h13.53c1.272,0 2.308,-1.034 2.308,-2.307V5.282C20.989,4.01 19.954,2.975 18.682,2.975z"
|
||||
android:fillColor="@color/white"/>
|
||||
</vector>
|
|
@ -4,8 +4,7 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context=".plugins.pump.omnipod.dialogs.InitPodWizard">
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -29,7 +28,7 @@
|
|||
android:layout_gravity="bottom"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/exit"
|
||||
android:text="@string/omnipod_wizard_button_exit"
|
||||
android:textAppearance="@android:style/TextAppearance.Material.Medium"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
@ -75,7 +74,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/transparent"
|
||||
android:onClick="showPreviousPage"
|
||||
android:text="@string/previous_button"
|
||||
android:text="@string/omnipod_wizard_button_previous"
|
||||
android:textColor="#FFFFFF" />
|
||||
|
||||
<View
|
||||
|
@ -89,7 +88,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/transparent"
|
||||
android:onClick="showNextPage"
|
||||
android:text="@string/next_button"
|
||||
android:text="@string/omnipod_wizard_button_next"
|
||||
android:textColor="#FFFFFF" />
|
||||
|
||||
<Button
|
||||
|
@ -98,7 +97,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/transparent"
|
||||
android:onClick="finishSetupWizard"
|
||||
android:text="@string/setupwizard_finish"
|
||||
android:text="@string/omnipod_wizard_button_finish"
|
||||
android:textColor="#FFFFFF" />
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -42,8 +42,8 @@
|
|||
android:id="@+id/initAction_textErrorMessage"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:layout_marginStart="15dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:textSize="15sp"
|
||||
android:layout_weight="0.3"
|
||||
style="@style/WizardPagePodContent"
|
||||
|
@ -54,8 +54,8 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0.7"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="15dp"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginEnd="15dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:drawableTop="@drawable/ic_actions_refill"
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
|
||||
|
||||
<ListView android:id="@+id/podInfoList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:saveEnabled="false"
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
android:minHeight="@dimen/list_item_height_small"
|
||||
android:orientation="horizontal"
|
||||
android:baselineAligned="true"
|
||||
android:paddingLeft="@dimen/list_item_padding_left"
|
||||
android:paddingRight="@dimen/list_item_padding_right"
|
||||
android:paddingStart="@dimen/list_item_padding_left"
|
||||
android:paddingEnd="@dimen/list_item_padding_right"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingBottom="12dp">
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
|||
android:ellipsize="end"
|
||||
android:layout_width="100sp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="16dp" />
|
||||
android:layout_marginEnd="16dp" />
|
||||
|
||||
<TextView android:id="@android:id/text2"
|
||||
style="?android:textAppearanceMedium"
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
tools:context=".plugins.pump.omnipod.dialogs.PodHistoryActivity">
|
||||
android:paddingBottom="@dimen/activity_vertical_margin">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/omnipod_historytop"
|
||||
|
@ -17,28 +15,27 @@
|
|||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:text="Type:"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:text="@string/omnipod_history_type"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/omnipod_historytype"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="20dp" />
|
||||
android:layout_marginEnd="20dp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="right"
|
||||
android:layout_marginRight="5dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/pillborder"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/omnipod_cmd_pod_history" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
|
|
|
@ -1,33 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp"
|
||||
android:paddingLeft="20dp">
|
||||
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="20dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/omnipod_history_time"
|
||||
android:layout_width="88dp"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical"
|
||||
android:text="Date"
|
||||
android:textSize="12dp" />
|
||||
android:text="@string/omnipod_history_item_date"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/omnipod_history_source"
|
||||
android:layout_width="132dp"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical"
|
||||
android:text="Source"
|
||||
android:textSize="12dp" />
|
||||
android:text="@string/omnipod_history_item_source"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/omnipod_history_description"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:text="Description"
|
||||
android:gravity="center_vertical"
|
||||
android:textSize="12dp" />
|
||||
android:text="@string/omnipod_history_item_description"
|
||||
android:textSize="12sp" />
|
||||
|
||||
</LinearLayout>
|
|
@ -46,7 +46,7 @@
|
|||
<TextView
|
||||
android:id="@+id/initpod_waiting_for_rl_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_marginRight="10dp"
|
||||
|
|
5
omnipod/src/main/res/values/colors.xml
Normal file
5
omnipod/src/main/res/values/colors.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="black_overlay">#66000000</color>
|
||||
<color name="ribbonWarning">#f4d700</color>
|
||||
</resources>
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
<!-- Omnipod - Base -->
|
||||
<string name="omnipod_name" translatable="false">Omnipod</string>
|
||||
<string name="omnipod_name_short" translatable="false">POD</string>
|
||||
<string name="omnipod_name_short" translatable="false">Pod</string>
|
||||
<string name="description_pump_omnipod">Pump integration for Omnipod, requires RileyLink (with at least 2.0 firmware) device.</string>
|
||||
|
||||
<!-- Omnipod Configuration -->
|
||||
|
@ -16,6 +16,10 @@
|
|||
<string name="key_omnipod_suspend_delivery_button_enabled" translatable="false">AAPS.Omnipod.suspend_delivery_button_enabled</string>
|
||||
<string name="key_omnipod_pulse_log_button_enabled" translatable="false">AAPS.Omnipod.pulse_log_button_enabled</string>
|
||||
<string name="key_omnipod_time_change_event_enabled" translatable="false">AAPS.Omnipod.time_change_enabled</string>
|
||||
<string name="key_omnipod_expiration_reminder_enabled" translatable="false">AAPS.Omnipod.expiration_reminder_enabled</string>
|
||||
<string name="key_omnipod_expiration_reminder_hours_before_shutdown" translatable="false">AAPS.Omnipod.expiration_reminder_hours_before_shutdown</string>
|
||||
<string name="key_omnipod_low_reservoir_alert_enabled" translatable="false">AAPS.Omnipod.low_reservoir_alert_enabled</string>
|
||||
<string name="key_omnipod_low_reservoir_alert_units" translatable="false">AAPS.Omnipod.low_reservoir_alert_units</string>
|
||||
<string name="omnipod_config_bolus_beeps_enabled">Bolus beeps enabled</string>
|
||||
<string name="omnipod_config_basal_beeps_enabled">Basal beeps enabled</string>
|
||||
<string name="omnipod_config_smb_beeps_enabled">SMB beeps enabled</string>
|
||||
|
@ -23,6 +27,10 @@
|
|||
<string name="omnipod_config_suspend_delivery_button_enabled">Suspend Delivery button enabled</string>
|
||||
<string name="omnipod_config_pulse_log_button_enabled">Pulse Log button enabled</string>
|
||||
<string name="omnipod_config_time_change_enabled">DST/Time zone detection enabled</string>
|
||||
<string name="omnipod_config_expiration_reminder_enabled">Expiration reminder enabled</string>
|
||||
<string name="omnipod_config_expiration_reminder_hours_before_shutdown">Hours before shutdown</string>
|
||||
<string name="omnipod_config_low_reservoir_alert_enabled">Low reservoir alert enabled</string>
|
||||
<string name="omnipod_config_low_reservoir_alert_units">Number of units</string>
|
||||
|
||||
<!-- Omnipod - Fragment -->
|
||||
<string name="omnipod_moments_ago">Moments ago</string>
|
||||
|
@ -133,12 +141,15 @@
|
|||
<string name="omnipod_alert_shutdown_imminent">Shutdown is imminent</string>
|
||||
<string name="omnipod_alert_low_reservoir">Low reservoir</string>
|
||||
<string name="omnipod_alert_unknown_alert">Unknown alert</string>
|
||||
<string name="omnipod_error_set_basal_failed_delivery_might_be_suspended">Setting basal profile might have failed. Delivery might be suspended! Please refresh Pod status and resume delivery from the Omnipod tab if needed.</string>
|
||||
<string name="omnipod_error_set_basal_failed_delivery_suspended">Setting basal profile failed. Delivery is suspended! Please resume delivery from the Omnipod tab.</string>
|
||||
<string name="omnipod_error_set_temp_basal_failed_old_tbr_might_be_cancelled">Setting temp basal might have failed. If a temp basal was already running, it might have been cancelled without AndroidAPS being aware!</string>
|
||||
<string name="omnipod_error_set_time_failed_delivery_might_be_suspended">Setting time might have failed. Delivery might be suspended! Please refresh Pod status and resume delivery from the Omnipod tab if needed.</string>
|
||||
<string name="omnipod_error_set_time_failed_delivery_suspended">Setting time failed. Delivery is suspended! Please resume delivery from the Omnipod tab.</string>
|
||||
<string name="omnipod_bolus_failed_uncertain">Unable to verify whether the bolus succeeded. Please verify that your Pod is bolusing or cancel the bolus.</string>
|
||||
<string name="omnipod_error_set_basal_failed_delivery_might_be_suspended">Setting basal profile failed. Delivery might be suspended! Please manually refresh the Pod status from the Omnipod tab and resume delivery if needed.</string>
|
||||
<string name="omnipod_error_set_basal_might_have_failed_delivery_might_be_suspended">Setting basal profile might have failed. Delivery might be suspended! Please manually refresh the Pod status from the Omnipod tab and resume delivery if needed.</string>
|
||||
<string name="omnipod_error_set_basal_failed_delivery_suspended">Setting basal profile failed. Delivery is suspended! Please manually resume delivery from the Omnipod tab.</string>
|
||||
<string name="omnipod_error_set_temp_basal_failed_old_tbr_might_be_cancelled">Setting temp basal failed. If a temp basal was previously running, it might have been cancelled. Please manually refresh the Pod status from the Omnipod tab.</string>
|
||||
<string name="omnipod_error_set_temp_basal_failed_old_tbr_cancelled_new_might_have_failed">Setting temp might have basal failed. If a temp basal was previously running, it has been cancelled. Please manually refresh the Pod status from the Omnipod tab.</string>
|
||||
<string name="omnipod_error_set_time_failed_delivery_might_be_suspended">Setting time might have failed. Delivery might be suspended! Please manually refresh the Pod status from the Omnipod tab and resume delivery if needed.</string>
|
||||
<string name="omnipod_error_set_time_failed_delivery_suspended">Setting time failed. Delivery is suspended! Please manually resume delivery from the Omnipod tab.</string>
|
||||
<string name="omnipod_bolus_failed_uncertain">Unable to verify whether the bolus succeeded. Please manually verify that your Pod is bolusing by listening to clicks. <b>If you are sure that the bolus didn\'t succeed, you should manually delete the bolus entry from Treatments, even if you click \'Cancel bolus\' now!</b></string>
|
||||
<string name="omnipod_bolus_failed_uncertain_smb">Unable to verify whether SMB bolus (%1$.2f U) succeeded. <b>If you are sure that the Bolus didn\'t succeed, you should manually delete the SMB entry from Treatments.</b></string>
|
||||
<string name="omnipod_rl_stats">RL stats</string>
|
||||
<string name="omnipod_read_pulse_log_short">Pulse log</string>
|
||||
<string name="omnipod_pod_lot">LOT</string>
|
||||
|
@ -165,6 +176,20 @@
|
|||
<string name="omnipod_cancelled_old_tbr_failed_to_set_new">Cancelled the old temporary basal, but failed to set new temporary basal</string>
|
||||
<string name="omnipod_cmd_set_fake_suspended_tbr">Set fake temporary basal because the Pod is suspended</string>
|
||||
<string name="omnipod_cmd_cancel_fake_suspended_tbr">Cancel fake temporary basal that was created because the Pod was suspended</string>
|
||||
<string name="omnipod_uncertain">uncertain</string>
|
||||
<string name="omnipod_expiration_alerts_updated">Alert configuration updated in Pod</string>
|
||||
<string name="omnipod_preference_category_rileylink">RileyLink</string>
|
||||
<string name="omnipod_preference_category_other">Other</string>
|
||||
<string name="omnipod_preference_category_alerts">Alerts</string>
|
||||
<string name="omnipod_preference_category_confirmation_beeps">Confirmation beeps</string>
|
||||
<string name="omnipod_wizard_button_exit">Exit</string>
|
||||
<string name="omnipod_wizard_button_previous">Previous</string>
|
||||
<string name="omnipod_wizard_button_next">Next</string>
|
||||
<string name="omnipod_wizard_button_finish">Finish</string>
|
||||
<string name="omnipod_history_item_description">Description</string>
|
||||
<string name="omnipod_history_item_source">Source</string>
|
||||
<string name="omnipod_history_item_date">Date</string>
|
||||
<string name="omnipod_history_type">Type:</string>
|
||||
|
||||
<plurals name="omnipod_minutes">
|
||||
<item quantity="one">%1$d minute</item>
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:layout_marginBottom">8dp</item>
|
||||
<item name="android:paddingLeft">20px</item>
|
||||
<item name="android:paddingRight">20px</item>
|
||||
<item name="android:paddingLeft">20dp</item>
|
||||
<item name="android:paddingRight">20dp</item>
|
||||
<item name="android:textSize">18sp</item>
|
||||
</style>
|
||||
|
||||
|
@ -14,10 +14,10 @@
|
|||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:layout_marginBottom">20dp</item>
|
||||
<item name="android:layout_marginTop">20dp</item>
|
||||
<item name="android:paddingTop">20px</item>
|
||||
<item name="android:paddingBottom">20px</item>
|
||||
<item name="android:paddingLeft">60px</item>
|
||||
<item name="android:paddingRight">60px</item>
|
||||
<item name="android:paddingTop">20dp</item>
|
||||
<item name="android:paddingBottom">20dp</item>
|
||||
<item name="android:paddingLeft">60dp</item>
|
||||
<item name="android:paddingRight">60dp</item>
|
||||
<item name="android:textSize">18sp</item>
|
||||
</style>
|
||||
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
xmlns:validate="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="@string/omnipod_name"
|
||||
app:initialExpandedChildrenCount="0">
|
||||
<PreferenceCategory android:title="@string/omnipod_preference_category_rileylink">
|
||||
|
||||
<Preference
|
||||
android:enabled="true"
|
||||
|
@ -14,6 +12,10 @@
|
|||
<intent android:action="info.nightscout.androidaps.plugins.PumpCommon.dialog.RileyLinkBLEScanActivity" />
|
||||
</Preference>
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/omnipod_preference_category_confirmation_beeps">
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/key_omnipod_bolus_beeps_enabled"
|
||||
|
@ -34,6 +36,46 @@
|
|||
android:key="@string/key_omnipod_tbr_beeps_enabled"
|
||||
android:title="@string/omnipod_config_tbr_beeps_enabled" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/omnipod_preference_category_alerts">
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/key_omnipod_expiration_reminder_enabled"
|
||||
android:title="@string/omnipod_config_expiration_reminder_enabled" />
|
||||
|
||||
<info.nightscout.androidaps.utils.textValidator.ValidatingEditTextPreference
|
||||
android:defaultValue="9"
|
||||
android:dependency="@string/key_omnipod_expiration_reminder_enabled"
|
||||
android:digits="0123456789"
|
||||
android:inputType="number"
|
||||
android:key="@string/key_omnipod_expiration_reminder_hours_before_shutdown"
|
||||
android:title="@string/omnipod_config_expiration_reminder_hours_before_shutdown"
|
||||
validate:maxNumber="24"
|
||||
validate:minNumber="2"
|
||||
validate:testType="numericRange" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/key_omnipod_low_reservoir_alert_enabled"
|
||||
android:title="@string/omnipod_config_low_reservoir_alert_enabled" />
|
||||
|
||||
<info.nightscout.androidaps.utils.textValidator.ValidatingEditTextPreference
|
||||
android:defaultValue="20"
|
||||
android:dependency="@string/key_omnipod_low_reservoir_alert_enabled"
|
||||
android:digits="0123456789"
|
||||
android:inputType="number"
|
||||
android:key="@string/key_omnipod_low_reservoir_alert_units"
|
||||
android:title="@string/omnipod_config_low_reservoir_alert_units"
|
||||
validate:maxNumber="50"
|
||||
validate:minNumber="5"
|
||||
validate:testType="numericRange" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/omnipod_preference_category_other">
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_omnipod_suspend_delivery_button_enabled"
|
||||
|
@ -50,4 +92,5 @@
|
|||
android:title="@string/omnipod_config_time_change_enabled" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
</androidx.preference.PreferenceScreen>
|
|
@ -41,7 +41,7 @@ public class PodInfoResponseTest {
|
|||
|
||||
assertEquals(PodInfoType.FAULT_EVENT, podInfoResponse.getSubType());
|
||||
|
||||
PodInfoFaultEvent podInfo = podInfoResponse.getPodInfo();
|
||||
PodInfoFaultEvent podInfo = (PodInfoFaultEvent) podInfoResponse.getPodInfo();
|
||||
assertFalse(podInfo.isFaultAccessingTables());
|
||||
assertEquals(LogEventErrorCode.INTERNAL_2_BIT_VARIABLE_SET_AND_MANIPULATED_IN_MAIN_LOOP_ROUTINES_2, podInfo.getLogEventErrorType());
|
||||
}
|
||||
|
@ -53,6 +53,6 @@ public class PodInfoResponseTest {
|
|||
assertEquals(PodInfoType.FAULT_EVENT, podInfoResponse.getSubType());
|
||||
|
||||
thrown.expect(ClassCastException.class);
|
||||
PodInfoActiveAlerts podInfo = podInfoResponse.getPodInfo();
|
||||
PodInfoActiveAlerts podInfo = (PodInfoActiveAlerts) podInfoResponse.getPodInfo();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import org.mockito.Mock;
|
|||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.FirmwareVersion;
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus;
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP;
|
||||
|
@ -21,6 +22,7 @@ import static org.junit.Assert.assertEquals;
|
|||
public class AapsPodStateManagerTest {
|
||||
@Mock AAPSLogger aapsLogger;
|
||||
@Mock SP sp;
|
||||
@Mock RxBusWrapper rxBus;
|
||||
|
||||
@Test
|
||||
public void times() {
|
||||
|
@ -31,7 +33,7 @@ public class AapsPodStateManagerTest {
|
|||
|
||||
DateTimeUtils.setCurrentMillisFixed(now.getMillis());
|
||||
|
||||
AapsPodStateManager podStateManager = new AapsPodStateManager(aapsLogger, sp);
|
||||
AapsPodStateManager podStateManager = new AapsPodStateManager(aapsLogger, sp, rxBus);
|
||||
podStateManager.initState(0x0);
|
||||
podStateManager.setInitializationParameters(0, 0, new FirmwareVersion(1, 1, 1),
|
||||
new FirmwareVersion(2, 2, 2), timeZone, PodProgressStatus.ABOVE_FIFTY_UNITS);
|
||||
|
@ -49,7 +51,7 @@ public class AapsPodStateManagerTest {
|
|||
|
||||
DateTimeUtils.setCurrentMillisFixed(now.getMillis());
|
||||
|
||||
AapsPodStateManager podStateManager = new AapsPodStateManager(aapsLogger, sp);
|
||||
AapsPodStateManager podStateManager = new AapsPodStateManager(aapsLogger, sp, rxBus);
|
||||
podStateManager.initState(0x0);
|
||||
podStateManager.setInitializationParameters(0, 0, new FirmwareVersion(1, 1, 1),
|
||||
new FirmwareVersion(2, 2, 2), timeZone, PodProgressStatus.ABOVE_FIFTY_UNITS);
|
||||
|
@ -72,7 +74,7 @@ public class AapsPodStateManagerTest {
|
|||
|
||||
DateTimeUtils.setCurrentMillisFixed(now.getMillis());
|
||||
|
||||
AapsPodStateManager podStateManager = new AapsPodStateManager(aapsLogger, sp);
|
||||
AapsPodStateManager podStateManager = new AapsPodStateManager(aapsLogger, sp, rxBus);
|
||||
podStateManager.initState(0x0);
|
||||
podStateManager.setInitializationParameters(0, 0, new FirmwareVersion(1, 1, 1),
|
||||
new FirmwareVersion(2, 2, 2), timeZone, PodProgressStatus.ABOVE_FIFTY_UNITS);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package info.nightscout.androidaps.dependencyInjection
|
||||
package info.nightscout.androidaps.plugins.pump.common.dagger
|
||||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
Loading…
Reference in a new issue