diff --git a/app/build.gradle b/app/build.gradle index 31d430687c..057c0da30e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -111,7 +111,7 @@ android { defaultConfig { multiDexEnabled true versionCode 1500 - version "2.8.2.1-dev-e" + version "2.8.2.1-dev-e1" buildConfigField "String", "VERSION", '"' + version + '"' buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"' buildConfigField "String", "REMOTE", '"' + generateGitRemote() + '"' diff --git a/app/src/main/java/info/nightscout/androidaps/db/CompatDBHelper.kt b/app/src/main/java/info/nightscout/androidaps/db/CompatDBHelper.kt index aef3c28a3b..42978b9324 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/CompatDBHelper.kt +++ b/app/src/main/java/info/nightscout/androidaps/db/CompatDBHelper.kt @@ -1,14 +1,12 @@ package info.nightscout.androidaps.db import info.nightscout.androidaps.database.AppRepository -import info.nightscout.androidaps.database.entities.Food -import info.nightscout.androidaps.database.entities.GlucoseValue -import info.nightscout.androidaps.database.entities.TemporaryTarget -import info.nightscout.androidaps.database.entities.TherapyEvent +import info.nightscout.androidaps.database.entities.* import info.nightscout.androidaps.events.EventFoodDatabaseChanged import info.nightscout.androidaps.events.EventNewBG import info.nightscout.androidaps.events.EventTempTargetChange import info.nightscout.androidaps.events.EventTherapyEventChange +import info.nightscout.androidaps.events.EventTreatmentChange import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.plugins.bus.RxBusWrapper @@ -50,5 +48,13 @@ class CompatDBHelper @Inject constructor( aapsLogger.debug(LTag.DATABASE, "Firing EventFoodDatabaseChanged") rxBus.send(EventFoodDatabaseChanged()) } + it.filterIsInstance().firstOrNull()?.let { + aapsLogger.debug(LTag.DATABASE, "Firing EventFoodDatabaseChanged") + rxBus.send(EventTreatmentChange(null)) + } + it.filterIsInstance().firstOrNull()?.let { + aapsLogger.debug(LTag.DATABASE, "Firing EventFoodDatabaseChanged") + rxBus.send(EventTreatmentChange(null)) + } } } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/FragmentsModule.kt b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/FragmentsModule.kt index 4acdd1f0db..011faded5b 100644 --- a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/FragmentsModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/FragmentsModule.kt @@ -66,7 +66,7 @@ abstract class FragmentsModule { @ContributesAndroidInjector abstract fun contributesTidepoolFragment(): TidepoolFragment @ContributesAndroidInjector abstract fun contributesTreatmentsFragment(): TreatmentsFragment - @ContributesAndroidInjector abstract fun contributesTreatmentsBolusFragment(): TreatmentsBolusFragment + @ContributesAndroidInjector abstract fun contributesTreatmentsBolusFragment(): TreatmentsMealLinkFragment @ContributesAndroidInjector abstract fun contributesTreatmentsTemporaryBasalsFragment(): TreatmentsTemporaryBasalsFragment @ContributesAndroidInjector abstract fun contributesTreatmentsTempTargetFragment(): TreatmentsTempTargetFragment @ContributesAndroidInjector abstract fun contributesTreatmentsExtendedBolusesFragment(): TreatmentsExtendedBolusesFragment diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt index 2dd44d1727..8883bb6c72 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt @@ -1,5 +1,6 @@ package info.nightscout.androidaps.dialogs +import android.content.Context import android.os.Bundle import android.text.Editable import android.text.TextWatcher @@ -8,13 +9,15 @@ import android.view.View import android.view.ViewGroup import com.google.common.base.Joiner import info.nightscout.androidaps.Constants -import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.R +import info.nightscout.androidaps.activities.ErrorHelperActivity +import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.Profile import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.entities.TemporaryTarget -import info.nightscout.androidaps.database.entities.TherapyEvent -import info.nightscout.androidaps.database.entities.UserEntry.* +import info.nightscout.androidaps.database.entities.UserEntry.Action +import info.nightscout.androidaps.database.entities.UserEntry.Units +import info.nightscout.androidaps.database.entities.UserEntry.ValueWithUnit import info.nightscout.androidaps.database.transactions.InsertTemporaryTargetAndCancelCurrentTransaction import info.nightscout.androidaps.databinding.DialogCarbsBinding import info.nightscout.androidaps.interfaces.Constraint @@ -24,8 +27,9 @@ import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.general.nsclient.NSUpload import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin -import info.nightscout.androidaps.plugins.treatments.CarbsGenerator import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin +import info.nightscout.androidaps.queue.Callback +import info.nightscout.androidaps.queue.CommandQueue import info.nightscout.androidaps.utils.* import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.extensions.formatColor @@ -40,7 +44,7 @@ import kotlin.math.max class CarbsDialog : DialogFragmentWithDate() { - @Inject lateinit var mainApp: MainApp + @Inject lateinit var ctx: Context @Inject lateinit var resourceHelper: ResourceHelper @Inject lateinit var constraintChecker: ConstraintChecker @Inject lateinit var defaultValueHelper: DefaultValueHelper @@ -48,9 +52,9 @@ class CarbsDialog : DialogFragmentWithDate() { @Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var iobCobCalculatorPlugin: IobCobCalculatorPlugin @Inject lateinit var nsUpload: NSUpload - @Inject lateinit var carbsGenerator: CarbsGenerator @Inject lateinit var uel: UserEntryLogger @Inject lateinit var carbTimer: CarbTimer + @Inject lateinit var commandQueue: CommandQueue @Inject lateinit var repository: AppRepository companion object { @@ -76,15 +80,15 @@ class CarbsDialog : DialogFragmentWithDate() { val time = binding.time.value.toInt() if (time > 12 * 60 || time < -12 * 60) { binding.time.value = 0.0 - ToastUtils.showToastInUiThread(mainApp, resourceHelper.gs(R.string.constraintapllied)) + ToastUtils.showToastInUiThread(ctx, resourceHelper.gs(R.string.constraintapllied)) } if (binding.duration.value > 10) { binding.duration.value = 0.0 - ToastUtils.showToastInUiThread(mainApp, resourceHelper.gs(R.string.constraintapllied)) + ToastUtils.showToastInUiThread(ctx, resourceHelper.gs(R.string.constraintapllied)) } if (binding.carbs.value.toInt() > maxCarbs) { binding.carbs.value = 0.0 - ToastUtils.showToastInUiThread(mainApp, resourceHelper.gs(R.string.carbsconstraintapplied)) + ToastUtils.showToastInUiThread(ctx, resourceHelper.gs(R.string.carbsconstraintapplied)) } } @@ -270,13 +274,39 @@ class CarbsDialog : DialogFragmentWithDate() { } } if (carbsAfterConstraints > 0) { - if (duration == 0) { - carbsGenerator.createCarb(carbsAfterConstraints, time, TherapyEvent.Type.CARBS_CORRECTION, notes) + val detailedBolusInfo = DetailedBolusInfo() + detailedBolusInfo.eventType = DetailedBolusInfo.EventType.CORRECTION_BOLUS + detailedBolusInfo.carbs = carbsAfterConstraints.toDouble() + detailedBolusInfo.context = context + detailedBolusInfo.notes = notes + detailedBolusInfo.carbsDuration = T.mins(duration.toLong()).msecs() + if (duration != 0 || timeOffset != 0) { + detailedBolusInfo.carbsTimestamp = time + disposable += repository.runTransactionForResult(detailedBolusInfo.insertMealLinkTransaction()) + .subscribe({ result -> + result.inserted.forEach { + uel.log(Action.CARBS, notes, + ValueWithUnit(eventTime, Units.Timestamp, eventTimeChanged), + ValueWithUnit(carbsAfterConstraints, Units.G), + ValueWithUnit(timeOffset, Units.M, timeOffset != 0), + ValueWithUnit(duration, Units.H, duration != 0) + ) + nsUpload.uploadMealLinkRecord(it) + } + }, { + aapsLogger.error(LTag.BGSOURCE, "Error while saving meal link", it) + }) } else { - carbsGenerator.generateCarbs(carbsAfterConstraints, time, duration, notes) - nsUpload.uploadEvent(TherapyEvent.Type.NOTE.text, DateUtil.now() - 2000, resourceHelper.gs(R.string.generated_ecarbs_note, carbsAfterConstraints, duration, timeOffset)) + commandQueue.bolus(detailedBolusInfo, object : Callback() { + override fun run() { + if (!result.success) { + ErrorHelperActivity.runAlarm(ctx, result.comment, resourceHelper.gs(R.string.treatmentdeliveryerror), R.raw.boluserror) + } else + uel.log(Action.BOLUS, notes, ValueWithUnit(carbsAfterConstraints, Units.G)) + + } + }) } - uel.log(Action.CARBS, notes, ValueWithUnit(eventTime, Units.Timestamp, eventTimeChanged), ValueWithUnit(carbsAfterConstraints, Units.G), ValueWithUnit(timeOffset, Units.M, timeOffset != 0), ValueWithUnit(duration, Units.H, duration != 0)) } if (useAlarm && carbs > 0 && timeOffset > 0) { carbTimer.scheduleReminder(dateUtil._now() + T.mins(timeOffset.toLong()).msecs()) diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/CareDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/CareDialog.kt index 122b38cd81..9e84b39f7a 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/CareDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/CareDialog.kt @@ -1,5 +1,6 @@ package info.nightscout.androidaps.dialogs +import android.content.Context import android.os.Bundle import android.text.Editable import android.text.TextWatcher @@ -10,13 +11,14 @@ import androidx.annotation.StringRes import com.google.common.base.Joiner import dagger.android.HasAndroidInjector import info.nightscout.androidaps.Constants -import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.R import info.nightscout.androidaps.data.Profile import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.entities.TherapyEvent +import info.nightscout.androidaps.database.entities.UserEntry.Action +import info.nightscout.androidaps.database.entities.UserEntry.Units +import info.nightscout.androidaps.database.entities.UserEntry.ValueWithUnit import info.nightscout.androidaps.database.transactions.InsertTherapyEventIfNewTransaction -import info.nightscout.androidaps.database.entities.UserEntry.* import info.nightscout.androidaps.databinding.DialogCareBinding import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.logging.LTag @@ -38,7 +40,7 @@ import javax.inject.Inject class CareDialog : DialogFragmentWithDate() { @Inject lateinit var injector: HasAndroidInjector - @Inject lateinit var mainApp: MainApp + @Inject lateinit var ctx: Context @Inject lateinit var resourceHelper: ResourceHelper @Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var nsUpload: NSUpload diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt index 0bb99da85e..7327691855 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt @@ -10,7 +10,6 @@ import info.nightscout.androidaps.R import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.database.AppRepository -import info.nightscout.androidaps.database.entities.Bolus import info.nightscout.androidaps.database.entities.TherapyEvent import info.nightscout.androidaps.database.entities.UserEntry.Action import info.nightscout.androidaps.database.entities.UserEntry.Units @@ -183,7 +182,7 @@ class FillDialog : DialogFragmentWithDate() { val detailedBolusInfo = DetailedBolusInfo() detailedBolusInfo.insulin = insulin detailedBolusInfo.context = context - detailedBolusInfo.bolusType = Bolus.Type.PRIMING + detailedBolusInfo.bolusType = DetailedBolusInfo.BolusType.PRIMING detailedBolusInfo.notes = notes commandQueue.bolus(detailedBolusInfo, object : Callback() { override fun run() { diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt index 917007d684..ac07b5664e 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt @@ -16,7 +16,6 @@ import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.Profile import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.entities.TemporaryTarget -import info.nightscout.androidaps.database.entities.TherapyEvent import info.nightscout.androidaps.database.entities.UserEntry.Action import info.nightscout.androidaps.database.entities.UserEntry.Units import info.nightscout.androidaps.database.entities.UserEntry.ValueWithUnit @@ -206,22 +205,32 @@ class InsulinDialog : DialogFragmentWithDate() { } if (insulinAfterConstraints > 0) { val detailedBolusInfo = DetailedBolusInfo() - detailedBolusInfo.eventType = TherapyEvent.Type.CORRECTION_BOLUS + detailedBolusInfo.eventType = DetailedBolusInfo.EventType.CORRECTION_BOLUS detailedBolusInfo.insulin = insulinAfterConstraints detailedBolusInfo.context = context detailedBolusInfo.notes = notes if (recordOnlyChecked) { - uel.log(Action.BOLUS_RECORD, notes, ValueWithUnit(insulinAfterConstraints, Units.U), ValueWithUnit(timeOffset, Units.M, timeOffset != 0)) - detailedBolusInfo.timestamp = time - activePlugin.activeTreatments.addToHistoryTreatment(detailedBolusInfo, false) + detailedBolusInfo.bolusTimestamp = time + disposable += repository.runTransactionForResult(detailedBolusInfo.insertMealLinkTransaction()) + .subscribe({ result -> + result.inserted.forEach { + uel.log(Action.BOLUS_RECORD, notes, + ValueWithUnit(it.bolus?.amount ?: 0.0, Units.U), + ValueWithUnit(timeOffset, Units.M, timeOffset != 0) + ) + nsUpload.uploadMealLinkRecord(it) + } + }, { + aapsLogger.error(LTag.BGSOURCE, "Error while saving meal link", it) + }) } else { - uel.log(Action.BOLUS, notes, ValueWithUnit(insulinAfterConstraints, Units.U)) - detailedBolusInfo.timestamp = DateUtil.now() commandQueue.bolus(detailedBolusInfo, object : Callback() { override fun run() { if (!result.success) { ErrorHelperActivity.runAlarm(ctx, result.comment, resourceHelper.gs(R.string.treatmentdeliveryerror), info.nightscout.androidaps.dana.R.raw.boluserror) - } + } else + uel.log(Action.BOLUS, notes, ValueWithUnit(insulinAfterConstraints, Units.U)) + } }) } diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt index 4887cf2b2b..e819e98c30 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt @@ -12,7 +12,7 @@ import info.nightscout.androidaps.Config import info.nightscout.androidaps.R import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.data.DetailedBolusInfo -import info.nightscout.androidaps.database.entities.TherapyEvent +import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.entities.UserEntry.Action import info.nightscout.androidaps.database.entities.UserEntry.Units import info.nightscout.androidaps.database.entities.UserEntry.ValueWithUnit @@ -20,8 +20,10 @@ import info.nightscout.androidaps.databinding.DialogTreatmentBinding import info.nightscout.androidaps.interfaces.ActivePluginProvider import info.nightscout.androidaps.interfaces.CommandQueueProvider import info.nightscout.androidaps.interfaces.Constraint +import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.plugins.general.nsclient.NSUpload import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.DecimalFormatter import info.nightscout.androidaps.utils.HtmlHelper @@ -30,6 +32,8 @@ import info.nightscout.androidaps.utils.ToastUtils import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.extensions.formatColor import info.nightscout.androidaps.utils.resources.ResourceHelper +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.rxkotlin.plusAssign import java.text.DecimalFormat import java.util.* import javax.inject.Inject @@ -44,6 +48,10 @@ class TreatmentDialog : DialogFragmentWithDate() { @Inject lateinit var ctx: Context @Inject lateinit var config: Config @Inject lateinit var uel: UserEntryLogger + @Inject lateinit var nsUpload: NSUpload + @Inject lateinit var repository: AppRepository + + private val disposable = CompositeDisposable() private val textWatcher: TextWatcher = object : TextWatcher { override fun afterTextChanged(s: Editable) {} @@ -131,10 +139,9 @@ class TreatmentDialog : DialogFragmentWithDate() { if (insulinAfterConstraints > 0 || carbsAfterConstraints > 0) { activity?.let { activity -> OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.overview_treatment_label), HtmlHelper.fromHtml(Joiner.on("
").join(actions)), { - uel.log(Action.TREATMENT, ValueWithUnit(insulin, Units.U, insulin != 0.0), ValueWithUnit(carbs, Units.G, carbs != 0)) val detailedBolusInfo = DetailedBolusInfo() - if (insulinAfterConstraints == 0.0) detailedBolusInfo.eventType = TherapyEvent.Type.CARBS_CORRECTION - if (carbsAfterConstraints == 0) detailedBolusInfo.eventType = TherapyEvent.Type.CORRECTION_BOLUS + if (insulinAfterConstraints == 0.0) detailedBolusInfo.eventType = DetailedBolusInfo.EventType.CARBS_CORRECTION + if (carbsAfterConstraints == 0) detailedBolusInfo.eventType = DetailedBolusInfo.EventType.CORRECTION_BOLUS detailedBolusInfo.insulin = insulinAfterConstraints detailedBolusInfo.carbs = carbsAfterConstraints.toDouble() detailedBolusInfo.context = context @@ -143,11 +150,27 @@ class TreatmentDialog : DialogFragmentWithDate() { override fun run() { if (!result.success) { ErrorHelperActivity.runAlarm(ctx, result.comment, resourceHelper.gs(R.string.treatmentdeliveryerror), info.nightscout.androidaps.dana.R.raw.boluserror) - } + } else + uel.log(Action.TREATMENT, + ValueWithUnit(insulin, Units.U, insulin != 0.0), + ValueWithUnit(carbs, Units.G, carbs != 0) + ) } }) - } else - activePlugin.activeTreatments.addToHistoryTreatment(detailedBolusInfo, false) + } else { + disposable += repository.runTransactionForResult(detailedBolusInfo.insertMealLinkTransaction()) + .subscribe({ result -> + result.inserted.forEach { + uel.log(Action.TREATMENT, + ValueWithUnit(insulin, Units.U, insulin != 0.0), + ValueWithUnit(carbs, Units.G, carbs != 0) + ) + nsUpload.uploadMealLinkRecord(it) + } + }, { + aapsLogger.error(LTag.BGSOURCE, "Error while saving meal link", it) + }) + } }) } } else diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt index 4b4744e6ea..043332aa4a 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt @@ -1,5 +1,6 @@ package info.nightscout.androidaps.dialogs +import android.content.Context import android.os.Bundle import android.text.Editable import android.text.TextWatcher @@ -16,7 +17,6 @@ import androidx.fragment.app.FragmentManager import dagger.android.HasAndroidInjector import dagger.android.support.DaggerDialogFragment import info.nightscout.androidaps.Constants -import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.R import info.nightscout.androidaps.data.Profile import info.nightscout.androidaps.database.AppRepository @@ -32,7 +32,11 @@ import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin -import info.nightscout.androidaps.utils.* +import info.nightscout.androidaps.utils.DateUtil +import info.nightscout.androidaps.utils.DecimalFormatter +import info.nightscout.androidaps.utils.FabricPrivacy +import info.nightscout.androidaps.utils.SafeParse +import info.nightscout.androidaps.utils.ToastUtils import info.nightscout.androidaps.utils.extensions.toVisibility import info.nightscout.androidaps.utils.extensions.valueToUnits import info.nightscout.androidaps.utils.resources.ResourceHelper @@ -51,7 +55,7 @@ class WizardDialog : DaggerDialogFragment() { @Inject lateinit var aapsLogger: AAPSLogger @Inject lateinit var aapsSchedulers: AapsSchedulers @Inject lateinit var constraintChecker: ConstraintChecker - @Inject lateinit var mainApp: MainApp + @Inject lateinit var ctx: Context @Inject lateinit var sp: SP @Inject lateinit var rxBus: RxBusWrapper @Inject lateinit var fabricPrivacy: FabricPrivacy @@ -180,7 +184,7 @@ class WizardDialog : DaggerDialogFragment() { // profile spinner binding.profile.onItemSelectedListener = object : OnItemSelectedListener { override fun onNothingSelected(parent: AdapterView<*>?) { - ToastUtils.showToastInUiThread(mainApp, resourceHelper.gs(R.string.noprofileselected)) + ToastUtils.showToastInUiThread(ctx, resourceHelper.gs(R.string.noprofileselected)) binding.ok.visibility = View.GONE } @@ -245,7 +249,7 @@ class WizardDialog : DaggerDialogFragment() { val profileStore = activePlugin.activeProfileInterface.profile if (profile == null || profileStore == null) { - ToastUtils.showToastInUiThread(mainApp, resourceHelper.gs(R.string.noprofile)) + ToastUtils.showToastInUiThread(ctx, resourceHelper.gs(R.string.noprofile)) dismiss() return } @@ -309,7 +313,7 @@ class WizardDialog : DaggerDialogFragment() { val carbsAfterConstraint = constraintChecker.applyCarbsConstraints(Constraint(carbs)).value() if (abs(carbs - carbsAfterConstraint) > 0.01) { binding.carbsInput.value = 0.0 - ToastUtils.showToastInUiThread(mainApp, resourceHelper.gs(R.string.carbsconstraintapplied)) + ToastUtils.showToastInUiThread(ctx, resourceHelper.gs(R.string.carbsconstraintapplied)) return } @@ -326,8 +330,8 @@ class WizardDialog : DaggerDialogFragment() { val carbTime = SafeParse.stringToInt(binding.carbTimeInput.text) - wizard = BolusWizard(mainApp).doCalc(specificProfile, profileName, tempTarget, carbsAfterConstraint, cob, bg, correction, - sp.getInt(R.string.key_boluswizard_percentage, 100).toDouble(), + wizard = BolusWizard(injector).doCalc(specificProfile, profileName, tempTarget, carbsAfterConstraint, cob, bg, correction, + sp.getInt(R.string.key_boluswizard_percentage, 100), binding.bgcheckbox.isChecked, binding.cobcheckbox.isChecked, binding.bolusiobcheckbox.isChecked, diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/WizardInfoDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/WizardInfoDialog.kt index aa76bde8c3..1327b08ab2 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/WizardInfoDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/WizardInfoDialog.kt @@ -9,12 +9,12 @@ import android.view.WindowManager import dagger.android.support.DaggerDialogFragment import info.nightscout.androidaps.Constants import info.nightscout.androidaps.R +import info.nightscout.androidaps.data.Profile +import info.nightscout.androidaps.database.entities.BolusCalculatorResult import info.nightscout.androidaps.databinding.DialogWizardinfoBinding import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.utils.DecimalFormatter -import info.nightscout.androidaps.utils.JsonHelper import info.nightscout.androidaps.utils.resources.ResourceHelper -import org.json.JSONObject import javax.inject.Inject class WizardInfoDialog : DaggerDialogFragment() { @@ -22,10 +22,12 @@ class WizardInfoDialog : DaggerDialogFragment() { @Inject lateinit var resourceHelper: ResourceHelper @Inject lateinit var profileFunction: ProfileFunction - private var json: JSONObject? = null + private lateinit var data: BolusCalculatorResult + private lateinit var notes: String - fun setData(json: JSONObject) { - this.json = json + fun setData(bolusCalculatorResult: BolusCalculatorResult, notes: String) { + this.data = bolusCalculatorResult + this.notes = notes } private var _binding: DialogWizardinfoBinding? = null @@ -49,44 +51,42 @@ class WizardInfoDialog : DaggerDialogFragment() { binding.close.setOnClickListener { dismiss() } val units = profileFunction.getUnits() - val bgString = - if (units == Constants.MGDL) DecimalFormatter.to0Decimal(JsonHelper.safeGetDouble(json, "bg")) - else DecimalFormatter.to1Decimal(JsonHelper.safeGetDouble(json, "bg")) + val bgString = Profile.toUnitsString(data.glucoseValue, data.glucoseValue * Constants.MGDL_TO_MMOLL, units) // BG - binding.bg.text = resourceHelper.gs(R.string.format_bg_isf, bgString, JsonHelper.safeGetDouble(json, "isf")) - binding.bginsulin.text = resourceHelper.gs(R.string.formatinsulinunits, JsonHelper.safeGetDouble(json, "insulinbg")) - binding.bgcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "insulinbgused") - binding.ttcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "ttused") + binding.bg.text = resourceHelper.gs(R.string.format_bg_isf, bgString, data.isf) + binding.bginsulin.text = resourceHelper.gs(R.string.formatinsulinunits, data.glucoseInsulin) + binding.bgcheckbox.isChecked = data.wasGlucoseUsed + binding.ttcheckbox.isChecked = data.wasTempTargetUsed // Trend - binding.bgtrend.text = JsonHelper.safeGetString(json, "trend") - binding.bgtrendinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, JsonHelper.safeGetDouble(json, "insulintrend")) - binding.bgtrendcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "trendused") + binding.bgtrend.text = DecimalFormatter.to1Decimal(data.glucoseTrend) + binding.bgtrendinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, data.trendInsulin) + binding.bgtrendcheckbox.isChecked = data.wasTrendUsed // COB - binding.cob.text = resourceHelper.gs(R.string.format_cob_ic, JsonHelper.safeGetDouble(json, "cob"), JsonHelper.safeGetDouble(json, "ic")) - binding.cobinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, JsonHelper.safeGetDouble(json, "insulincob")) - binding.cobcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "cobused") + binding.cob.text = resourceHelper.gs(R.string.format_cob_ic, data.cob, data.ic) + binding.cobinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, data.cobInsulin) + binding.cobcheckbox.isChecked = data.wasCOBUsed // Bolus IOB - binding.bolusiobinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, JsonHelper.safeGetDouble(json, "bolusiob")) - binding.bolusiobcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "bolusiobused") + binding.bolusiobinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, data.bolusIOB) + binding.bolusiobcheckbox.isChecked = data.wasBolusIOBUsed // Basal IOB - binding.basaliobinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, JsonHelper.safeGetDouble(json, "basaliob")) - binding.basaliobcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "basaliobused") + binding.basaliobinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, data.basalIOB) + binding.basaliobcheckbox.isChecked = data.wasBasalIOBUsed // Superbolus - binding.sbinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, JsonHelper.safeGetDouble(json, "insulinsuperbolus")) - binding.sbcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "superbolusused") + binding.sbinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, data.superbolusInsulin) + binding.sbcheckbox.isChecked = data.wasSuperbolusUsed // Carbs - binding.carbs.text = resourceHelper.gs(R.string.format_carbs_ic, JsonHelper.safeGetDouble(json, "carbs"), JsonHelper.safeGetDouble(json, "ic")) - binding.carbsinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, JsonHelper.safeGetDouble(json, "insulincarbs")) + binding.carbs.text = resourceHelper.gs(R.string.format_carbs_ic, data.carbs, data.ic) + binding.carbsinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, data.carbsInsulin) // Correction - binding.correctioninsulin.text = resourceHelper.gs(R.string.formatinsulinunits, JsonHelper.safeGetDouble(json, "othercorrection")) + binding.correctioninsulin.text = resourceHelper.gs(R.string.formatinsulinunits, data.otherCorrection) // Profile - binding.profile.text = JsonHelper.safeGetString(json, "profile") + binding.profile.text = data.profileName // Notes - binding.notes.text = JsonHelper.safeGetString(json, "notes") + binding.notes.text = notes // Percentage - binding.percentUsed.text = resourceHelper.gs(R.string.format_percent, (JsonHelper.safeGetInt(json, "percentageCorrection", 100))) + binding.percentUsed.text = resourceHelper.gs(R.string.format_percent, data.percentageCorrection) // Total - binding.totalinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, JsonHelper.safeGetDouble(json, "insulin")) + binding.totalinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, data.totalInsulin) } override fun onStart() { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.kt index acc23da5a0..5e4d6e9864 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.kt @@ -16,7 +16,6 @@ import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.Profile import info.nightscout.androidaps.data.PumpEnactResult import info.nightscout.androidaps.database.AppRepository -import info.nightscout.androidaps.database.entities.Bolus import info.nightscout.androidaps.database.entities.TherapyEvent import info.nightscout.androidaps.database.transactions.InsertTherapyEventIfNewTransaction import info.nightscout.androidaps.events.EventAcceptOpenLoopChange @@ -596,9 +595,9 @@ open class LoopPlugin @Inject constructor( // deliver SMB val detailedBolusInfo = DetailedBolusInfo() detailedBolusInfo.lastKnownBolusTime = treatmentsPlugin.lastBolusTime - detailedBolusInfo.eventType = TherapyEvent.Type.CORRECTION_BOLUS + detailedBolusInfo.eventType = DetailedBolusInfo.EventType.CORRECTION_BOLUS detailedBolusInfo.insulin = request.smb - detailedBolusInfo.bolusType = Bolus.Type.SMB + detailedBolusInfo.bolusType = DetailedBolusInfo.BolusType.SMB detailedBolusInfo.deliverAtTheLatest = request.deliverAt aapsLogger.debug(LTag.APS, "applyAPSRequest: bolus()") commandQueue.bolus(detailedBolusInfo, callback) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/safety/SafetyPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/safety/SafetyPlugin.kt index 0a5e1927e9..c5d778eb4b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/safety/SafetyPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/safety/SafetyPlugin.kt @@ -124,7 +124,7 @@ class SafetyPlugin @Inject constructor( val pump = activePlugin.activePump // check for pump max if (pump.pumpDescription.tempBasalStyle == PumpDescription.ABSOLUTE) { - val pumpLimit = pump.pumpDescription.pumpType.tbrSettings.maxDose + val pumpLimit = pump.pumpDescription.pumpType.tbrSettings?.maxDose ?: 0.0 absoluteRate.setIfSmaller(aapsLogger, pumpLimit, String.format(resourceHelper.gs(R.string.limitingbasalratio), pumpLimit, resourceHelper.gs(R.string.pumplimit)), this) } @@ -147,7 +147,7 @@ class SafetyPlugin @Inject constructor( percentRateAfterConst = if (percentRateAfterConst < 100) Round.ceilTo(percentRateAfterConst.toDouble(), pump.pumpDescription.tempPercentStep.toDouble()).toInt() else Round.floorTo(percentRateAfterConst.toDouble(), pump.pumpDescription.tempPercentStep.toDouble()).toInt() percentRate[aapsLogger, percentRateAfterConst, String.format(resourceHelper.gs(R.string.limitingpercentrate), percentRateAfterConst, resourceHelper.gs(R.string.pumplimit))] = this if (pump.pumpDescription.tempBasalStyle == PumpDescription.PERCENT) { - val pumpLimit = pump.pumpDescription.pumpType.tbrSettings.maxDose + val pumpLimit = pump.pumpDescription.pumpType.tbrSettings?.maxDose ?: 0.0 percentRate.setIfSmaller(aapsLogger, pumpLimit.toInt(), String.format(resourceHelper.gs(R.string.limitingbasalratio), pumpLimit, resourceHelper.gs(R.string.pumplimit)), this) } return percentRate diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt index 1f8228d5d8..6c76c3f910 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt @@ -643,7 +643,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList } pump.isSuspended() -> { - binding.infoLayout.apsMode.setImageResource(if (pump.model() == PumpType.Omnipod_Eros || pump.model() == PumpType.Omnipod_Dash) { + binding.infoLayout.apsMode.setImageResource(if (pump.model() == PumpType.OMNIPOD_EROS || pump.model() == PumpType.OMNIPOD_DASH) { // For Omnipod, indicate the pump as disconnected when it's suspended. // The only way to 'reconnect' it, is through the Omnipod tab R.drawable.ic_loop_disconnected diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/StatusLightHandler.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/StatusLightHandler.kt index e4f5074afe..ad6ce90b1e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/StatusLightHandler.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/StatusLightHandler.kt @@ -43,7 +43,7 @@ class StatusLightHandler @Inject constructor( handleAge(careportal_pb_age, TherapyEvent.Type.PUMP_BATTERY_CHANGE, R.string.key_statuslights_bage_warning, 216.0, R.string.key_statuslights_bage_critical, 240.0) } if (!config.NSCLIENT) { - if (pump.model() == PumpType.Omnipod_Eros || pump.model() == PumpType.Omnipod_Dash) { + if (pump.model() == PumpType.OMNIPOD_EROS || pump.model() == PumpType.OMNIPOD_DASH) { handleOmnipodReservoirLevel(careportal_reservoir_level, R.string.key_statuslights_res_critical, 10.0, R.string.key_statuslights_res_warning, 80.0, pump.reservoirLevel, "U") } else { handleLevel(careportal_reservoir_level, R.string.key_statuslights_res_critical, 10.0, R.string.key_statuslights_res_warning, 80.0, pump.reservoirLevel, "U") @@ -55,15 +55,15 @@ class StatusLightHandler @Inject constructor( } if (!config.NSCLIENT) { - if (pump.model() == PumpType.Omnipod_Dash) { + if (pump.model() == PumpType.OMNIPOD_DASH) { // Omnipod Dash does not report its battery level careportal_battery_level?.text = resourceHelper.gs(R.string.notavailable) careportal_battery_level?.setTextColor(Color.WHITE) - } else if (pump.model() == PumpType.Omnipod_Eros && pump is OmnipodErosPumpPlugin) { // instance of check is needed because at startup, pump can still be VirtualPumpPlugin and that will cause a crash because of the class cast below + } else if (pump.model() == PumpType.OMNIPOD_EROS && pump is OmnipodErosPumpPlugin) { // instance of check is needed because at startup, pump can still be VirtualPumpPlugin and that will cause a crash because of the class cast below // The Omnipod Eros does not report its battery level. However, some RileyLink alternatives do. // Depending on the user's configuration, we will either show the battery level reported by the RileyLink or "n/a" handleOmnipodErosBatteryLevel(careportal_battery_level, R.string.key_statuslights_bat_critical, 26.0, R.string.key_statuslights_bat_warning, 51.0, pump.batteryLevel.toDouble(), "%", pump.isUseRileyLinkBatteryLevel) - } else if (pump.model() != PumpType.AccuChekCombo) { + } else if (pump.model() != PumpType.ACCU_CHEK_COMBO) { handleLevel(careportal_battery_level, R.string.key_statuslights_bat_critical, 26.0, R.string.key_statuslights_bat_warning, 51.0, pump.batteryLevel.toDouble(), "%") } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt index 38e2a8cace..49420b2c8f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt @@ -637,7 +637,7 @@ class SmsCommunicatorPlugin @Inject constructor( }) } else if (divided[1].endsWith("%")) { var tempBasalPct = SafeParse.stringToInt(StringUtils.removeEnd(divided[1], "%")) - val durationStep = activePlugin.activePump.model().tbrSettings.durationStep + val durationStep = activePlugin.activePump.model().tbrSettings?.durationStep ?: 60 var duration = 30 if (divided.size > 2) duration = SafeParse.stringToInt(divided[2]) val profile = profileFunction.getProfile() @@ -674,7 +674,7 @@ class SmsCommunicatorPlugin @Inject constructor( } } else { var tempBasal = SafeParse.stringToDouble(divided[1]) - val durationStep = activePlugin.activePump.model().tbrSettings.durationStep + val durationStep = activePlugin.activePump.model().tbrSettings?.durationStep ?: 60 var duration = 30 if (divided.size > 2) duration = SafeParse.stringToInt(divided[2]) val profile = profileFunction.getProfile() diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/comm/TidepoolUploader.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/comm/TidepoolUploader.kt index faaa1b40d6..99b86b990d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/comm/TidepoolUploader.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/tidepool/comm/TidepoolUploader.kt @@ -4,7 +4,6 @@ import android.content.Context import android.os.PowerManager import android.os.SystemClock import info.nightscout.androidaps.BuildConfig -import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.R import info.nightscout.androidaps.interfaces.ActivePluginProvider import info.nightscout.androidaps.logging.AAPSLogger @@ -17,8 +16,8 @@ import info.nightscout.androidaps.plugins.general.tidepool.messages.DatasetReply import info.nightscout.androidaps.plugins.general.tidepool.messages.OpenDatasetRequestMessage import info.nightscout.androidaps.plugins.general.tidepool.messages.UploadReplyMessage import info.nightscout.androidaps.utils.DateUtil -import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.T +import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.sharedPreferences.SP import okhttp3.MediaType.Companion.toMediaTypeOrNull @@ -34,7 +33,7 @@ import javax.inject.Singleton class TidepoolUploader @Inject constructor( private val aapsLogger: AAPSLogger, private val rxBus: RxBusWrapper, - private val mainApp: MainApp, + private val ctx: Context, private val resourceHelper: ResourceHelper, private val sp: SP, private val uploadChunk: UploadChunk, @@ -45,6 +44,7 @@ class TidepoolUploader @Inject constructor( private var wl: PowerManager.WakeLock? = null companion object { + private const val INTEGRATION_BASE_URL = "https://int-api.tidepool.org" private const val PRODUCTION_BASE_URL = "https://api.tidepool.org" internal const val VERSION = "0.0.1" @@ -285,7 +285,7 @@ class TidepoolUploader @Inject constructor( @Synchronized private fun extendWakeLock(ms: Long) { if (wl == null) { - val pm = mainApp.getSystemService(Context.POWER_SERVICE) as PowerManager + val pm = ctx.getSystemService(Context.POWER_SERVICE) as PowerManager wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AndroidAPS:TidepoolUploader") wl?.acquire(ms) } else { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/ActionStringHandler.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/ActionStringHandler.kt index cf2c58ebdb..e6d7b0d793 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/ActionStringHandler.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/ActionStringHandler.kt @@ -15,9 +15,7 @@ import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.Profile import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.ValueWrapper -import info.nightscout.androidaps.database.entities.Bolus import info.nightscout.androidaps.database.entities.TemporaryTarget -import info.nightscout.androidaps.database.entities.TherapyEvent import info.nightscout.androidaps.database.interfaces.end import info.nightscout.androidaps.database.transactions.CancelCurrentTemporaryTargetIfAnyTransaction import info.nightscout.androidaps.database.transactions.InsertTemporaryTargetAndCancelCurrentTransaction @@ -33,7 +31,6 @@ import info.nightscout.androidaps.plugins.general.wear.events.EventWearConfirmAc import info.nightscout.androidaps.plugins.general.wear.events.EventWearInitiateAction import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin -import info.nightscout.androidaps.plugins.treatments.CarbsGenerator import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.* import info.nightscout.androidaps.utils.extensions.valueToUnits @@ -77,7 +74,6 @@ class ActionStringHandler @Inject constructor( private val danaRv2Plugin: DanaRv2Plugin, private val danaRSPlugin: DanaRSPlugin, private val danaPump: DanaPump, - private val carbsGenerator: CarbsGenerator, private val dateUtil: DateUtil, private val config: Config, private val databaseHelper: DatabaseHelperInterface, @@ -221,7 +217,7 @@ class ActionStringHandler @Inject constructor( val bolusWizard = BolusWizard(injector).doCalc(profile, profileName, tempTarget, carbsAfterConstraints, if (cobInfo.displayCob != null) cobInfo.displayCob!! else 0.0, bgReading.valueToUnits(profileFunction.getUnits()), - 0.0, percentage.toDouble(), useBG, useCOB, useBolusIOB, useBasalIOB, false, useTT, useTrend, false) + 0.0, percentage, useBG, useCOB, useBolusIOB, useBasalIOB, false, useTT, useTrend, false) if (abs(bolusWizard.insulinAfterConstraints - bolusWizard.calculatedTotalInsulin) >= 0.01) { sendError("Insulin constraint violation!" + "\nCannot deliver " + format.format(bolusWizard.calculatedTotalInsulin) + "!") @@ -516,13 +512,13 @@ class ActionStringHandler @Inject constructor( generateTempTarget(duration, low, high) } else if ("wizard2" == act[0]) { if (lastBolusWizard != null) { //use last calculation as confirmed string matches - doBolus(lastBolusWizard!!.calculatedTotalInsulin, lastBolusWizard!!.carbs) + doBolus(lastBolusWizard!!.calculatedTotalInsulin, lastBolusWizard!!.carbs, null, 0) lastBolusWizard = null } } else if ("bolus" == act[0]) { val insulin = SafeParse.stringToDouble(act[1]) val carbs = SafeParse.stringToInt(act[2]) - doBolus(insulin, carbs) + doBolus(insulin, carbs, null, 0) } else if ("cppset" == act[0]) { val timeshift = SafeParse.stringToInt(act[1]) val percentage = SafeParse.stringToInt(act[2]) @@ -542,16 +538,6 @@ class ActionStringHandler @Inject constructor( lastBolusWizard = null } - private fun doECarbs(carbs: Int, time: Long, duration: Int) { - if (carbs > 0) { - if (duration == 0) { - carbsGenerator.createCarb(carbs, time, TherapyEvent.Type.CARBS_CORRECTION, "watch") - } else { - carbsGenerator.generateCarbs(carbs, time, duration, "watch eCarbs") - } - } - } - private fun setCPP(timeshift: Int, percentage: Int) { var msg = "" //check for validity @@ -604,7 +590,7 @@ class ActionStringHandler @Inject constructor( private fun doFillBolus(amount: Double) { val detailedBolusInfo = DetailedBolusInfo() detailedBolusInfo.insulin = amount - detailedBolusInfo.bolusType = Bolus.Type.PRIMING + detailedBolusInfo.bolusType = DetailedBolusInfo.BolusType.PRIMING commandQueue.bolus(detailedBolusInfo, object : Callback() { override fun run() { if (!result.success) { @@ -616,13 +602,19 @@ class ActionStringHandler @Inject constructor( }) } - private fun doBolus(amount: Double, carbs: Int) { + private fun doECarbs(carbs: Int, time: Long, duration: Int) { + doBolus(0.0, carbs, time, duration) + } + + private fun doBolus(amount: Double, carbs: Int, carbsTime: Long?, carbsDuration: Int) { val detailedBolusInfo = DetailedBolusInfo() detailedBolusInfo.insulin = amount detailedBolusInfo.carbs = carbs.toDouble() - detailedBolusInfo.bolusType = Bolus.Type.NORMAL + detailedBolusInfo.bolusType = DetailedBolusInfo.BolusType.NORMAL + detailedBolusInfo.carbsTimestamp = carbsTime + detailedBolusInfo.carbsDuration = carbsDuration.toLong() val storesCarbs = activePlugin.activePump.pumpDescription.storesCarbInfo - if (detailedBolusInfo.insulin > 0 || storesCarbs) { + if (detailedBolusInfo.insulin > 0 || (storesCarbs && carbsDuration == 0)) { commandQueue.bolus(detailedBolusInfo, object : Callback() { override fun run() { if (!result.success) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/WearPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/WearPlugin.kt index f3cdd7a7f2..e65c931268 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/WearPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/WearPlugin.kt @@ -1,9 +1,9 @@ package info.nightscout.androidaps.plugins.general.wear +import android.content.Context import android.content.Intent import dagger.Lazy import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.R import info.nightscout.androidaps.events.* import info.nightscout.androidaps.interfaces.PluginBase @@ -16,7 +16,6 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.general.overview.events.EventDismissBolusProgressIfRunning import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress import info.nightscout.androidaps.plugins.general.wear.wearintegration.WatchUpdaterService -import info.nightscout.androidaps.events.EventAutosensCalculationFinished import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.rx.AapsSchedulers @@ -32,7 +31,7 @@ class WearPlugin @Inject constructor( resourceHelper: ResourceHelper, private val aapsSchedulers: AapsSchedulers, private val sp: SP, - private val mainApp: MainApp, + private val ctx: Context, private val fabricPrivacy: FabricPrivacy, private val loopPlugin: Lazy, private val rxBus: RxBusWrapper @@ -96,10 +95,10 @@ class WearPlugin @Inject constructor( .observeOn(aapsSchedulers.io) .subscribe({ event: EventBolusRequested -> val status = String.format(resourceHelper.gs(R.string.bolusrequested), event.amount) - val intent = Intent(mainApp, WatchUpdaterService::class.java).setAction(WatchUpdaterService.ACTION_SEND_BOLUSPROGRESS) + val intent = Intent(ctx, WatchUpdaterService::class.java).setAction(WatchUpdaterService.ACTION_SEND_BOLUSPROGRESS) intent.putExtra("progresspercent", 0) intent.putExtra("progressstatus", status) - mainApp.startService(intent) + ctx.startService(intent) }, fabricPrivacy::logException)) disposable.add(rxBus .toObservable(EventDismissBolusProgressIfRunning::class.java) @@ -111,20 +110,20 @@ class WearPlugin @Inject constructor( } else { resourceHelper.gs(R.string.nosuccess) } - val intent = Intent(mainApp, WatchUpdaterService::class.java).setAction(WatchUpdaterService.ACTION_SEND_BOLUSPROGRESS) + val intent = Intent(ctx, WatchUpdaterService::class.java).setAction(WatchUpdaterService.ACTION_SEND_BOLUSPROGRESS) intent.putExtra("progresspercent", 100) intent.putExtra("progressstatus", status) - mainApp.startService(intent) + ctx.startService(intent) }, fabricPrivacy::logException)) disposable.add(rxBus .toObservable(EventOverviewBolusProgress::class.java) .observeOn(aapsSchedulers.io) .subscribe({ event: EventOverviewBolusProgress -> if (!event.isSMB() || sp.getBoolean("wear_notifySMB", true)) { - val intent = Intent(mainApp, WatchUpdaterService::class.java).setAction(WatchUpdaterService.ACTION_SEND_BOLUSPROGRESS) + val intent = Intent(ctx, WatchUpdaterService::class.java).setAction(WatchUpdaterService.ACTION_SEND_BOLUSPROGRESS) intent.putExtra("progresspercent", event.percent) intent.putExtra("progressstatus", event.status) - mainApp.startService(intent) + ctx.startService(intent) } }, fabricPrivacy::logException)) } @@ -139,47 +138,47 @@ class WearPlugin @Inject constructor( if (isEnabled(getType())) { // only start service when this plugin is enabled if (bgValue) { - mainApp.startService(Intent(mainApp, WatchUpdaterService::class.java)) + ctx.startService(Intent(ctx, WatchUpdaterService::class.java)) } if (basals) { - mainApp.startService(Intent(mainApp, WatchUpdaterService::class.java).setAction(WatchUpdaterService.ACTION_SEND_BASALS)) + ctx.startService(Intent(ctx, WatchUpdaterService::class.java).setAction(WatchUpdaterService.ACTION_SEND_BASALS)) } if (status) { - mainApp.startService(Intent(mainApp, WatchUpdaterService::class.java).setAction(WatchUpdaterService.ACTION_SEND_STATUS)) + ctx.startService(Intent(ctx, WatchUpdaterService::class.java).setAction(WatchUpdaterService.ACTION_SEND_STATUS)) } } } fun resendDataToWatch() { //Log.d(TAG, "WR: WearPlugin:resendDataToWatch"); - mainApp.startService(Intent(mainApp, WatchUpdaterService::class.java).setAction(WatchUpdaterService.ACTION_RESEND)) + ctx.startService(Intent(ctx, WatchUpdaterService::class.java).setAction(WatchUpdaterService.ACTION_RESEND)) } fun openSettings() { //Log.d(TAG, "WR: WearPlugin:openSettings"); - mainApp.startService(Intent(mainApp, WatchUpdaterService::class.java).setAction(WatchUpdaterService.ACTION_OPEN_SETTINGS)) + ctx.startService(Intent(ctx, WatchUpdaterService::class.java).setAction(WatchUpdaterService.ACTION_OPEN_SETTINGS)) } fun requestNotificationCancel(actionString: String?) { //Log.d(TAG, "WR: WearPlugin:requestNotificationCancel"); - val intent = Intent(mainApp, WatchUpdaterService::class.java) + val intent = Intent(ctx, WatchUpdaterService::class.java) .setAction(WatchUpdaterService.ACTION_CANCEL_NOTIFICATION) intent.putExtra("actionstring", actionString) - mainApp.startService(intent) + ctx.startService(intent) } fun requestActionConfirmation(title: String, message: String, actionString: String) { - val intent = Intent(mainApp, WatchUpdaterService::class.java).setAction(WatchUpdaterService.ACTION_SEND_ACTIONCONFIRMATIONREQUEST) + val intent = Intent(ctx, WatchUpdaterService::class.java).setAction(WatchUpdaterService.ACTION_SEND_ACTIONCONFIRMATIONREQUEST) intent.putExtra("title", title) intent.putExtra("message", message) intent.putExtra("actionstring", actionString) - mainApp.startService(intent) + ctx.startService(intent) } fun requestChangeConfirmation(title: String, message: String, actionString: String) { - val intent = Intent(mainApp, WatchUpdaterService::class.java).setAction(WatchUpdaterService.ACTION_SEND_CHANGECONFIRMATIONREQUEST) + val intent = Intent(ctx, WatchUpdaterService::class.java).setAction(WatchUpdaterService.ACTION_SEND_CHANGECONFIRMATIONREQUEST) intent.putExtra("title", title) intent.putExtra("message", message) intent.putExtra("actionstring", actionString) - mainApp.startService(intent) + ctx.startService(intent) } } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefBasePlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefBasePlugin.kt index 1ffb885866..dd37e15c74 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefBasePlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefBasePlugin.kt @@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.insulin import dagger.android.HasAndroidInjector import info.nightscout.androidaps.R import info.nightscout.androidaps.data.Iob +import info.nightscout.androidaps.database.entities.Bolus import info.nightscout.androidaps.db.Treatment import info.nightscout.androidaps.interfaces.InsulinInterface import info.nightscout.androidaps.interfaces.PluginBase @@ -14,6 +15,8 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification import info.nightscout.androidaps.utils.resources.ResourceHelper +import kotlin.math.exp +import kotlin.math.pow /** * Created by adrian on 13.08.2017. @@ -84,6 +87,26 @@ abstract class InsulinOrefBasePlugin( return result } + override fun iobCalcForTreatment(bolus: Bolus, time: Long, dia: Double): Iob { + val result = Iob() + val peak = peak + if (bolus.amount != 0.0) { + val bolusTime = bolus.timestamp + val t = (time - bolusTime) / 1000.0 / 60.0 + val td = dia * 60 //getDIA() always >= MIN_DIA + val tp = peak.toDouble() + // force the IOB to 0 if over DIA hours have passed + if (t < td) { + val tau = tp * (1 - tp / td) / (1 - 2 * tp / td) + val a = 2 * tau / td + val S = 1 / (1 - a + (1 + a) * exp(-td / tau)) + result.activityContrib = bolus.amount * (S / tau.pow(2.0)) * t * (1 - t / td) * exp(-t / tau) + result.iobContrib = bolus.amount * (1 - S * (1 - a) * ((t.pow(2.0) / (tau * td * (1 - a)) - t / tau - 1) * Math.exp(-t / tau) + 1)) + } + } + return result + } + override val comment get(): String { var comment = commentStandardText() diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/virtual/VirtualPumpPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/pump/virtual/VirtualPumpPlugin.kt index 7d72e9deae..ef60a84ea8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/virtual/VirtualPumpPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/virtual/VirtualPumpPlugin.kt @@ -40,7 +40,7 @@ import javax.inject.Singleton import kotlin.math.min @Singleton -open class VirtualPumpPlugin @Inject constructor( +class VirtualPumpPlugin @Inject constructor( injector: HasAndroidInjector, aapsLogger: AAPSLogger, private val rxBus: RxBusWrapper, @@ -347,7 +347,7 @@ open class VirtualPumpPlugin @Inject constructor( } override fun manufacturer(): ManufacturerType { - return pumpDescription.pumpType.manufacturer + return pumpDescription.pumpType.manufacturer ?: ManufacturerType.AndroidAPS } override fun model(): PumpType { @@ -367,7 +367,7 @@ open class VirtualPumpPlugin @Inject constructor( } fun refreshConfiguration() { - val pumpType = sp.getString(R.string.key_virtualpump_type, PumpType.GenericAAPS.description) + val pumpType = sp.getString(R.string.key_virtualpump_type, PumpType.GENERIC_AAPS.description) val pumpTypeNew = PumpType.getByDescription(pumpType) aapsLogger.debug(LTag.PUMP, "Pump in configuration: $pumpType, PumpType object: $pumpTypeNew") if (this.pumpType == pumpTypeNew) return diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/CarbsGenerator.kt b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/CarbsGenerator.kt deleted file mode 100644 index 51a0d0b949..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/CarbsGenerator.kt +++ /dev/null @@ -1,58 +0,0 @@ -package info.nightscout.androidaps.plugins.treatments - -import android.content.Context -import info.nightscout.androidaps.R -import info.nightscout.androidaps.activities.ErrorHelperActivity -import info.nightscout.androidaps.data.DetailedBolusInfo -import info.nightscout.androidaps.database.entities.TherapyEvent -import info.nightscout.androidaps.interfaces.ActivePluginProvider -import info.nightscout.androidaps.interfaces.CommandQueueProvider -import info.nightscout.androidaps.queue.Callback -import info.nightscout.androidaps.utils.DateUtil -import info.nightscout.androidaps.utils.T -import info.nightscout.androidaps.utils.resources.ResourceHelper -import javax.inject.Inject -import javax.inject.Singleton -import kotlin.math.roundToInt - -@Singleton -class CarbsGenerator @Inject constructor( - private val resourceHelper: ResourceHelper, - private val activePlugin: ActivePluginProvider, - private val commandQueue: CommandQueueProvider, - private val context: Context -) { - - fun generateCarbs(amount: Int, startTime: Long, duration: Int, notes: String) { - var remainingCarbs = amount.toLong() - val ticks = duration * 4 //duration guaranteed to be integer greater zero - for (i in 0 until ticks) { - val carbTime = startTime + i * 15 * 60 * 1000 - val smallCarbAmount = (1.0 * remainingCarbs / (ticks - i)).roundToInt() //on last iteration (ticks-i) is 1 -> smallCarbAmount == remainingCarbs - remainingCarbs -= smallCarbAmount.toLong() - if (smallCarbAmount > 0) createCarb(smallCarbAmount, carbTime, TherapyEvent.Type.MEAL_BOLUS, notes) - } - } - - fun createCarb(carbs: Int, time: Long, eventType: TherapyEvent.Type, notes: String) { - val carbInfo = DetailedBolusInfo() - carbInfo.timestamp = time - carbInfo.eventType = eventType - carbInfo.carbs = carbs.toDouble() - carbInfo.context = context - carbInfo.notes = notes - if (activePlugin.activePump.pumpDescription.storesCarbInfo && carbInfo.timestamp <= DateUtil.now() && carbInfo.timestamp > DateUtil.now() - T.mins(2).msecs()) { - commandQueue.bolus(carbInfo, object : Callback() { - override fun run() { - if (!result.success) { - ErrorHelperActivity.runAlarm(context, result.comment, resourceHelper.gs(R.string.treatmentdeliveryerror), R.raw.boluserror) - } - } - }) - } else { - // Don't send to pump if it is in the future or more than 5 minutes in the past - // as pumps might return those as as "now" when reading the history. - activePlugin.activeTreatments.addToHistoryTreatment(carbInfo, false) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsFragment.kt index 6115ce9185..675788fc12 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsFragment.kt @@ -11,7 +11,6 @@ import info.nightscout.androidaps.R import info.nightscout.androidaps.databinding.TreatmentsFragmentBinding import info.nightscout.androidaps.events.EventExtendedBolusChange import info.nightscout.androidaps.interfaces.ActivePluginProvider -import info.nightscout.androidaps.interfaces.ConfigInterface import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.treatments.fragments.* import info.nightscout.androidaps.utils.FabricPrivacy @@ -51,7 +50,7 @@ class TreatmentsFragment : DaggerFragment() { binding.extendedBoluses.visibility = (buildHelper.isEngineeringMode() && !activePlugin.activePump.isFakingTempsByExtendedBoluses).toVisibility() binding.treatments.setOnClickListener { - setFragment(TreatmentsBolusFragment()) + setFragment(TreatmentsMealLinkFragment()) setBackgroundColorOnSelected(it) } binding.extendedBoluses.setOnClickListener { @@ -78,7 +77,7 @@ class TreatmentsFragment : DaggerFragment() { setFragment(TreatmentsUserEntryFragment()) setBackgroundColorOnSelected(it) } - setFragment(TreatmentsBolusFragment()) + setFragment(TreatmentsMealLinkFragment()) setBackgroundColorOnSelected(binding.treatments) } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsPlugin.java index e95f0be143..9b24b800d1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsPlugin.java @@ -26,8 +26,6 @@ import info.nightscout.androidaps.data.NonOverlappingIntervals; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.ProfileIntervals; import info.nightscout.androidaps.database.AppRepository; -import info.nightscout.androidaps.database.embedments.InterfaceIDs; -import info.nightscout.androidaps.database.entities.Bolus; import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.ProfileSwitch; import info.nightscout.androidaps.db.Source; @@ -55,6 +53,7 @@ import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification; import info.nightscout.androidaps.plugins.general.overview.notifications.Notification; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult; +import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin; import info.nightscout.androidaps.plugins.pump.medtronic.data.MedtronicHistoryData; import info.nightscout.androidaps.utils.DateUtil; @@ -626,11 +625,11 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface Treatment treatment = new Treatment(); treatment.date = detailedBolusInfo.timestamp; - treatment.source = (detailedBolusInfo.getPumpType() == InterfaceIDs.PumpType.USER) ? Source.USER : Source.PUMP; + treatment.source = (detailedBolusInfo.getPumpType() == PumpType.USER) ? Source.USER : Source.PUMP; treatment.pumpId = detailedBolusInfo.getBolusPumpId(); treatment.insulin = detailedBolusInfo.insulin; - treatment.isValid = detailedBolusInfo.getBolusType() != Bolus.Type.PRIMING; - treatment.isSMB = detailedBolusInfo.getBolusType() == Bolus.Type.SMB; + treatment.isValid = detailedBolusInfo.getBolusType() != DetailedBolusInfo.BolusType.PRIMING; + treatment.isSMB = detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB; if (detailedBolusInfo.carbTime == 0) treatment.carbs = detailedBolusInfo.carbs; treatment.mealBolus = treatment.carbs > 0; @@ -650,7 +649,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface if (detailedBolusInfo.carbTime != 0) { Treatment carbsTreatment = new Treatment(); - carbsTreatment.source = (detailedBolusInfo.getPumpType() == InterfaceIDs.PumpType.USER) ? Source.USER : Source.PUMP; + carbsTreatment.source = (detailedBolusInfo.getPumpType() == PumpType.USER) ? Source.USER : Source.PUMP; carbsTreatment.pumpId = detailedBolusInfo.getCarbsPumpId(); // but this should never happen carbsTreatment.date = detailedBolusInfo.timestamp + detailedBolusInfo.carbTime * 60 * 1000L + 1000L; // add 1 sec to make them different records carbsTreatment.carbs = detailedBolusInfo.carbs; @@ -663,7 +662,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface getService().createOrUpdateMedtronic(carbsTreatment, false); //log.debug("Adding new Treatment record" + carbsTreatment); } - if (newRecordCreated && detailedBolusInfo.getBolusType() != Bolus.Type.PRIMING) + if (newRecordCreated && detailedBolusInfo.getBolusType() != DetailedBolusInfo.BolusType.PRIMING) nsUpload.uploadTreatmentRecord(detailedBolusInfo); if (!allowUpdate && !creatOrUpdateResult.getSuccess()) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsBolusFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsBolusFragment.kt deleted file mode 100644 index 5b53f9a757..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsBolusFragment.kt +++ /dev/null @@ -1,210 +0,0 @@ -package info.nightscout.androidaps.plugins.treatments.fragments - -import android.graphics.Paint -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView -import dagger.android.support.DaggerFragment -import info.nightscout.androidaps.R -import info.nightscout.androidaps.database.entities.UserEntry.* -import info.nightscout.androidaps.databinding.TreatmentsBolusFragmentBinding -import info.nightscout.androidaps.databinding.TreatmentsBolusItemBinding -import info.nightscout.androidaps.db.Source -import info.nightscout.androidaps.db.Treatment -import info.nightscout.androidaps.dialogs.WizardInfoDialog -import info.nightscout.androidaps.events.EventTreatmentChange -import info.nightscout.androidaps.interfaces.ProfileFunction -import info.nightscout.androidaps.logging.UserEntryLogger -import info.nightscout.androidaps.plugins.bus.RxBusWrapper -import info.nightscout.androidaps.plugins.general.nsclient.NSUpload -import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart -import info.nightscout.androidaps.events.EventAutosensCalculationFinished -import info.nightscout.androidaps.interfaces.UploadQueueInterface -import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin -import info.nightscout.androidaps.plugins.treatments.fragments.TreatmentsBolusFragment.RecyclerViewAdapter.TreatmentsViewHolder -import info.nightscout.androidaps.utils.DateUtil -import info.nightscout.androidaps.utils.FabricPrivacy -import info.nightscout.androidaps.utils.alertDialogs.OKDialog -import info.nightscout.androidaps.utils.buildHelper.BuildHelper -import info.nightscout.androidaps.utils.resources.ResourceHelper -import info.nightscout.androidaps.utils.rx.AapsSchedulers -import info.nightscout.androidaps.utils.sharedPreferences.SP -import io.reactivex.disposables.CompositeDisposable -import javax.inject.Inject - -class TreatmentsBolusFragment : DaggerFragment() { - - private val disposable = CompositeDisposable() - - @Inject lateinit var rxBus: RxBusWrapper - @Inject lateinit var sp: SP - @Inject lateinit var resourceHelper: ResourceHelper - @Inject lateinit var fabricPrivacy: FabricPrivacy - @Inject lateinit var treatmentsPlugin: TreatmentsPlugin - @Inject lateinit var profileFunction: ProfileFunction - @Inject lateinit var nsUpload: NSUpload - @Inject lateinit var uploadQueue: UploadQueueInterface - @Inject lateinit var dateUtil: DateUtil - @Inject lateinit var buildHelper: BuildHelper - @Inject lateinit var aapsSchedulers: AapsSchedulers - @Inject lateinit var uel: UserEntryLogger - - private var _binding: TreatmentsBolusFragmentBinding? = null - - // This property is only valid between onCreateView and - // onDestroyView. - private val binding get() = _binding!! - - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View = - TreatmentsBolusFragmentBinding.inflate(inflater, container, false).also { _binding = it }.root - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - binding.recyclerview.setHasFixedSize(true) - binding.recyclerview.layoutManager = LinearLayoutManager(view.context) - binding.recyclerview.adapter = RecyclerViewAdapter(treatmentsPlugin.treatmentsFromHistory) - binding.refreshFromNightscout.setOnClickListener { - activity?.let { activity -> - OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.refresheventsfromnightscout) + "?") { - uel.log(Action.TREATMENTS_NS_REFRESH) - treatmentsPlugin.service.resetTreatments() - rxBus.send(EventNSClientRestart()) - } - } - } - binding.deleteFutureTreatments.setOnClickListener { - activity?.let { activity -> - OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.overview_treatment_label), resourceHelper.gs(R.string.deletefuturetreatments) + "?", Runnable { - uel.log(Action.DELETE_FUTURE_TREATMENTS) - val futureTreatments = treatmentsPlugin.service.getTreatmentDataFromTime(DateUtil.now() + 1000, true) - for (treatment in futureTreatments) { - if (NSUpload.isIdValid(treatment._id)) - nsUpload.removeCareportalEntryFromNS(treatment._id) - else - uploadQueue.removeByMongoId("dbAdd", treatment._id) - treatmentsPlugin.service.delete(treatment) - } - updateGui() - }) - } - } - val nsUploadOnly = sp.getBoolean(R.string.key_ns_upload_only, true) || !buildHelper.isEngineeringMode() - if (nsUploadOnly) binding.refreshFromNightscout.visibility = View.GONE - } - - @Synchronized - override fun onResume() { - super.onResume() - disposable.add(rxBus - .toObservable(EventTreatmentChange::class.java) - .observeOn(aapsSchedulers.main) - .subscribe({ updateGui() }, fabricPrivacy::logException) - ) - disposable.add(rxBus - .toObservable(EventAutosensCalculationFinished::class.java) - .observeOn(aapsSchedulers.main) - .subscribe({ updateGui() }, fabricPrivacy::logException) - ) - updateGui() - } - - @Synchronized - override fun onPause() { - super.onPause() - disposable.clear() - } - - @Synchronized - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - - inner class RecyclerViewAdapter internal constructor(var treatments: List) : RecyclerView.Adapter() { - - override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): TreatmentsViewHolder { - val v = LayoutInflater.from(viewGroup.context).inflate(R.layout.treatments_bolus_item, viewGroup, false) - return TreatmentsViewHolder(v) - } - - override fun onBindViewHolder(holder: TreatmentsViewHolder, position: Int) { - val profile = profileFunction.getProfile() ?: return - val t = treatments[position] - holder.binding.date.text = dateUtil.dateAndTimeString(t.date) - holder.binding.insulin.text = resourceHelper.gs(R.string.formatinsulinunits, t.insulin) - holder.binding.carbs.text = resourceHelper.gs(R.string.format_carbs, t.carbs.toInt()) - val iob = t.iobCalc(System.currentTimeMillis(), profile.dia) - holder.binding.iob.text = resourceHelper.gs(R.string.formatinsulinunits, iob.iobContrib) - holder.binding.mealOrCorrection.text = if (t.isSMB) "SMB" else if (t.mealBolus) resourceHelper.gs(R.string.mealbolus) else resourceHelper.gs(R.string.correctionbous) - holder.binding.pump.visibility = if (t.source == Source.PUMP) View.VISIBLE else View.GONE - holder.binding.ns.visibility = if (NSUpload.isIdValid(t._id)) View.VISIBLE else View.GONE - holder.binding.invalid.visibility = if (t.isValid) View.GONE else View.VISIBLE - if (iob.iobContrib != 0.0) holder.binding.iob.setTextColor(resourceHelper.gc(R.color.colorActive)) else holder.binding.iob.setTextColor(holder.binding.carbs.currentTextColor) - if (t.date > DateUtil.now()) holder.binding.date.setTextColor(resourceHelper.gc(R.color.colorScheduled)) else holder.binding.date.setTextColor(holder.binding.carbs.currentTextColor) - holder.binding.remove.tag = t - holder.binding.calculation.tag = t - holder.binding.calculation.visibility = if (t.getBoluscalc() == null) View.INVISIBLE else View.VISIBLE - } - - override fun getItemCount(): Int { - return treatments.size - } - - inner class TreatmentsViewHolder internal constructor(view: View) : RecyclerView.ViewHolder(view) { - - val binding = TreatmentsBolusItemBinding.bind(view) - - init { - binding.calculation.setOnClickListener { - val treatment = it.tag as Treatment - if (treatment.getBoluscalc() != null) { - val wizardDialog = WizardInfoDialog() - wizardDialog.setData(treatment.getBoluscalc()!!) - wizardDialog.show(childFragmentManager, "WizardInfoDialog") - } - } - binding.calculation.paintFlags = binding.calculation.paintFlags or Paint.UNDERLINE_TEXT_FLAG - binding.remove.setOnClickListener { - val treatment = it.tag as Treatment? ?: return@setOnClickListener - activity?.let { activity -> - val text = resourceHelper.gs(R.string.configbuilder_insulin) + ": " + - resourceHelper.gs(R.string.formatinsulinunits, treatment.insulin) + "\n" + - resourceHelper.gs(R.string.carbs) + ": " + resourceHelper.gs(R.string.format_carbs, treatment.carbs.toInt()) + "\n" + - resourceHelper.gs(R.string.date) + ": " + dateUtil.dateAndTimeString(treatment.date) - OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.removerecord), text, Runnable { - uel.log(Action.TREATMENT_REMOVED, ValueWithUnit(treatment.date, Units.Timestamp), ValueWithUnit(treatment.insulin, Units.U, treatment.insulin != 0.0), ValueWithUnit(treatment.carbs.toInt(), Units.G, treatment.carbs != 0.0)) - if (treatment.source == Source.PUMP) { - treatment.isValid = false - treatmentsPlugin.service.update(treatment) - } else { - if (NSUpload.isIdValid(treatment._id)) - nsUpload.removeCareportalEntryFromNS(treatment._id) - else - uploadQueue.removeByMongoId("dbAdd", treatment._id) - treatmentsPlugin.service.delete(treatment) - } - updateGui() - }) - } - } - binding.remove.paintFlags = binding.remove.paintFlags or Paint.UNDERLINE_TEXT_FLAG - } - } - } - - private fun updateGui() { - if (_binding == null) return - binding.recyclerview.swapAdapter(RecyclerViewAdapter(treatmentsPlugin.treatmentsFromHistory), false) - if (treatmentsPlugin.lastCalculationTreatments != null) { - binding.iobTotal.text = resourceHelper.gs(R.string.formatinsulinunits, treatmentsPlugin.lastCalculationTreatments.iob) - binding.iobActivityTotal.text = resourceHelper.gs(R.string.formatinsulinunits, treatmentsPlugin.lastCalculationTreatments.activity) - } - if (treatmentsPlugin.service.getTreatmentDataFromTime(DateUtil.now() + 1000, true).isNotEmpty()) - binding.deleteFutureTreatments.visibility = View.VISIBLE - else - binding.deleteFutureTreatments.visibility = View.GONE - } -} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsCareportalFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsCareportalFragment.kt index 666c38eb9c..8cb304ad0d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsCareportalFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsCareportalFragment.kt @@ -120,28 +120,28 @@ class TreatmentsCareportalFragment : DaggerFragment() { fun swapAdapter() { val now = System.currentTimeMillis() - if (binding.showInvalidated.isChecked) - repository - .getTherapyEventDataIncludingInvalidFromTime(now - millsToThePast, false) - .observeOn(aapsSchedulers.main) - .subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) } - else - repository - .getTherapyEventDataFromTime(now - millsToThePast, false) - .observeOn(aapsSchedulers.main) - .subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) } + disposable += + if (binding.showInvalidated.isChecked) + repository + .getTherapyEventDataIncludingInvalidFromTime(now - millsToThePast, false) + .observeOn(aapsSchedulers.main) + .subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) } + else + repository + .getTherapyEventDataFromTime(now - millsToThePast, false) + .observeOn(aapsSchedulers.main) + .subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) } } @Synchronized override fun onResume() { super.onResume() swapAdapter() - disposable.add(rxBus + disposable += rxBus .toObservable(EventTherapyEventChange::class.java) .observeOn(aapsSchedulers.main) .debounce(1L, TimeUnit.SECONDS) .subscribe({ swapAdapter() }, fabricPrivacy::logException) - ) disposable += rxBus .toObservable(EventTreatmentUpdateGui::class.java) // TODO join with above .observeOn(aapsSchedulers.io) @@ -193,10 +193,11 @@ class TreatmentsCareportalFragment : DaggerFragment() { val therapyEvent = v.tag as TherapyEvent activity?.let { activity -> val text = resourceHelper.gs(R.string.eventtype) + ": " + translator.translate(therapyEvent.type.text) + "\n" + - resourceHelper.gs(R.string.notes_label) + ": " + (therapyEvent.note ?: "") + "\n" + + resourceHelper.gs(R.string.notes_label) + ": " + (therapyEvent.note + ?: "") + "\n" + resourceHelper.gs(R.string.date) + ": " + dateUtil.dateAndTimeString(therapyEvent.timestamp) OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.removerecord), text, Runnable { - uel.log(Action.CAREPORTAL_REMOVED, therapyEvent.note , ValueWithUnit(therapyEvent.timestamp, Units.Timestamp), ValueWithUnit(therapyEvent.type.text, Units.TherapyEvent)) + uel.log(Action.CAREPORTAL_REMOVED, therapyEvent.note, ValueWithUnit(therapyEvent.timestamp, Units.Timestamp), ValueWithUnit(therapyEvent.type.text, Units.TherapyEvent)) disposable += repository.runTransactionForResult(InvalidateTherapyEventTransaction(therapyEvent.id)) .subscribe({ val id = therapyEvent.interfaceIDs.nightscoutId diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsMealLinkFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsMealLinkFragment.kt new file mode 100644 index 0000000000..84eef1d0b2 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/fragments/TreatmentsMealLinkFragment.kt @@ -0,0 +1,321 @@ +package info.nightscout.androidaps.plugins.treatments.fragments + +import android.graphics.Paint +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import dagger.android.support.DaggerFragment +import info.nightscout.androidaps.R +import info.nightscout.androidaps.data.Iob +import info.nightscout.androidaps.database.AppRepository +import info.nightscout.androidaps.database.entities.Bolus +import info.nightscout.androidaps.database.entities.MealLinkLoaded +import info.nightscout.androidaps.database.entities.UserEntry.* +import info.nightscout.androidaps.database.transactions.InvalidateBolusTransaction +import info.nightscout.androidaps.database.transactions.InvalidateCarbsTransaction +import info.nightscout.androidaps.database.transactions.InvalidateMealLinkTransaction +import info.nightscout.androidaps.databinding.TreatmentsMealLinkFragmentBinding +import info.nightscout.androidaps.databinding.TreatmentsMealLinkItemBinding +import info.nightscout.androidaps.dialogs.WizardInfoDialog +import info.nightscout.androidaps.events.EventAutosensCalculationFinished +import info.nightscout.androidaps.events.EventTreatmentChange +import info.nightscout.androidaps.interfaces.ActivePluginProvider +import info.nightscout.androidaps.interfaces.ProfileFunction +import info.nightscout.androidaps.interfaces.UploadQueueInterface +import info.nightscout.androidaps.logging.AAPSLogger +import info.nightscout.androidaps.logging.LTag +import info.nightscout.androidaps.logging.UserEntryLogger +import info.nightscout.androidaps.plugins.bus.RxBusWrapper +import info.nightscout.androidaps.plugins.general.nsclient.NSUpload +import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart +import info.nightscout.androidaps.plugins.treatments.events.EventTreatmentUpdateGui +import info.nightscout.androidaps.utils.DateUtil +import info.nightscout.androidaps.utils.FabricPrivacy +import info.nightscout.androidaps.utils.T +import info.nightscout.androidaps.utils.alertDialogs.OKDialog +import info.nightscout.androidaps.utils.buildHelper.BuildHelper +import info.nightscout.androidaps.utils.extensions.iobCalc +import info.nightscout.androidaps.utils.extensions.toVisibility +import info.nightscout.androidaps.utils.resources.ResourceHelper +import info.nightscout.androidaps.utils.rx.AapsSchedulers +import info.nightscout.androidaps.utils.sharedPreferences.SP +import io.reactivex.Completable +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.rxkotlin.plusAssign +import io.reactivex.rxkotlin.subscribeBy +import java.util.concurrent.TimeUnit +import javax.inject.Inject + +class TreatmentsMealLinkFragment : DaggerFragment() { + + @Inject lateinit var rxBus: RxBusWrapper + @Inject lateinit var sp: SP + @Inject lateinit var aapsLogger: AAPSLogger + @Inject lateinit var resourceHelper: ResourceHelper + @Inject lateinit var fabricPrivacy: FabricPrivacy + @Inject lateinit var profileFunction: ProfileFunction + @Inject lateinit var nsUpload: NSUpload + @Inject lateinit var uploadQueue: UploadQueueInterface + @Inject lateinit var dateUtil: DateUtil + @Inject lateinit var buildHelper: BuildHelper + @Inject lateinit var aapsSchedulers: AapsSchedulers + @Inject lateinit var uel: UserEntryLogger + @Inject lateinit var repository: AppRepository + @Inject lateinit var activePlugin: ActivePluginProvider + + private val disposable = CompositeDisposable() + + private val millsToThePast = T.days(30).msecs() + + private var _binding: TreatmentsMealLinkFragmentBinding? = null + + // This property is only valid between onCreateView and + // onDestroyView. + private val binding get() = _binding!! + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View = + TreatmentsMealLinkFragmentBinding.inflate(inflater, container, false).also { _binding = it }.root + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.recyclerview.setHasFixedSize(true) + binding.recyclerview.layoutManager = LinearLayoutManager(view.context) + + binding.refreshFromNightscout.setOnClickListener { + activity?.let { activity -> + OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.refresheventsfromnightscout) + "?") { + uel.log(Action.TREATMENTS_NS_REFRESH) + disposable += + Completable.fromAction { + repository.deleteAllMealLinks() + repository.deleteAllBoluses() + repository.deleteAllCarbs() + } + .subscribeOn(aapsSchedulers.io) + .observeOn(aapsSchedulers.main) + .subscribeBy( + onError = { aapsLogger.error("Error removing entries", it) }, + onComplete = { rxBus.send(EventTreatmentChange(null)) } + ) + rxBus.send(EventNSClientRestart()) + } + } + } + binding.deleteFutureTreatments.setOnClickListener { + activity?.let { activity -> + OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.overview_treatment_label), resourceHelper.gs(R.string.deletefuturetreatments) + "?", Runnable { + uel.log(Action.DELETE_FUTURE_TREATMENTS) + repository + .getMealLinkLoadedDataFromTime(dateUtil._now(), false) + .observeOn(aapsSchedulers.main) + .subscribe { list -> + list.forEach { mealLinkLoaded -> + disposable += repository.runTransactionForResult(InvalidateMealLinkTransaction(mealLinkLoaded.mealLink.id)) + .subscribe({ + if (mealLinkLoaded.bolus != null) { + val id = mealLinkLoaded.bolus!!.interfaceIDs.nightscoutId + if (NSUpload.isIdValid(id)) nsUpload.removeCareportalEntryFromNS(id) + else uploadQueue.removeByMongoId("dbAdd", mealLinkLoaded.bolus!!.timestamp.toString()) + } + if (mealLinkLoaded.carbs != null) { + val id = mealLinkLoaded.carbs!!.interfaceIDs.nightscoutId + if (NSUpload.isIdValid(id)) nsUpload.removeCareportalEntryFromNS(id) + else uploadQueue.removeByMongoId("dbAdd", mealLinkLoaded.carbs!!.timestamp.toString()) + } + }, { + aapsLogger.error(LTag.DATATREATMENTS, "Error while invalidating MealLink", it) + }) + } + binding.deleteFutureTreatments.visibility = View.GONE + } + + }) + } + } + val nsUploadOnly = sp.getBoolean(R.string.key_ns_upload_only, true) || !buildHelper.isEngineeringMode() + if (nsUploadOnly) binding.refreshFromNightscout.visibility = View.GONE + binding.showInvalidated.setOnCheckedChangeListener { _, _ -> + rxBus.send(EventTreatmentUpdateGui()) + } + } + + fun swapAdapter() { + val now = System.currentTimeMillis() + disposable += + if (binding.showInvalidated.isChecked) + repository + .getMealLinkLoadedDataIncludingInvalidFromTime(now - millsToThePast, false) + .observeOn(aapsSchedulers.main) + .subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) } + else + repository + .getMealLinkLoadedDataFromTime(now - millsToThePast, false) + .observeOn(aapsSchedulers.main) + .subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) } + disposable += repository + .getMealLinkLoadedDataFromTime(now, false) + .observeOn(aapsSchedulers.main) + .subscribe { list -> binding.deleteFutureTreatments.visibility = list.isNotEmpty().toVisibility() } + } + + @Synchronized + override fun onResume() { + super.onResume() + swapAdapter() + disposable += rxBus + .toObservable(EventTreatmentChange::class.java) + .observeOn(aapsSchedulers.main) + .debounce(1L, TimeUnit.SECONDS) + .subscribe({ swapAdapter() }, fabricPrivacy::logException) + disposable += rxBus + .toObservable(EventTreatmentUpdateGui::class.java) // TODO join with above + .observeOn(aapsSchedulers.io) + .debounce(1L, TimeUnit.SECONDS) + .subscribe({ swapAdapter() }, fabricPrivacy::logException) + disposable += rxBus + .toObservable(EventAutosensCalculationFinished::class.java) + .observeOn(aapsSchedulers.main) + .debounce(1L, TimeUnit.SECONDS) + .subscribe({ swapAdapter() }, fabricPrivacy::logException) + } + + @Synchronized + override fun onPause() { + super.onPause() + disposable.clear() + } + + @Synchronized + override fun onDestroyView() { + super.onDestroyView() + binding.recyclerview.adapter = null // avoid leaks + _binding = null + } + + inner class RecyclerViewAdapter internal constructor(var mealLinks: List) : RecyclerView.Adapter() { + + override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): MealLinkLoadedViewHolder { + val v = LayoutInflater.from(viewGroup.context).inflate(R.layout.treatments_meal_link_item, viewGroup, false) + return MealLinkLoadedViewHolder(v) + } + + override fun onBindViewHolder(holder: MealLinkLoadedViewHolder, position: Int) { + val profile = profileFunction.getProfile() ?: return + val ml = mealLinks[position] + + // MealLink + holder.binding.date.text = dateUtil.dateAndTimeString(ml.mealLink.timestamp) + val iob = ml.bolus?.iobCalc(activePlugin, System.currentTimeMillis(), profile.dia) + ?: Iob() + holder.binding.iob.text = resourceHelper.gs(R.string.formatinsulinunits, iob.iobContrib) + if (iob.iobContrib != 0.0) holder.binding.iob.setTextColor(resourceHelper.gc(R.color.colorActive)) else holder.binding.iob.setTextColor(holder.binding.carbs.currentTextColor) + if (ml.mealLink.timestamp > dateUtil._now()) holder.binding.date.setTextColor(resourceHelper.gc(R.color.colorScheduled)) else holder.binding.date.setTextColor(holder.binding.carbs.currentTextColor) + holder.binding.mealOrCorrection.text = + when (ml.bolus?.type) { + Bolus.Type.SMB -> "SMB" + Bolus.Type.NORMAL -> resourceHelper.gs(R.string.mealbolus) + else -> "" + } + holder.binding.calculation.visibility = (ml.bolusCalculatorResult != null).toVisibility() + + // Bolus + holder.binding.bolusLayout.visibility = (ml.bolus != null && (ml.bolus?.isValid == true || binding.showInvalidated.isChecked)).toVisibility() + holder.binding.bolusDate.text = dateUtil.timeString(ml.bolus?.timestamp ?: 0L) + holder.binding.insulin.text = resourceHelper.gs(R.string.formatinsulinunits, ml.bolus?.amount ?: 0.0) + holder.binding.bolusNs.visibility = (NSUpload.isIdValid(ml.bolus?.interfaceIDs?.nightscoutId)).toVisibility() + holder.binding.bolusPump.visibility = (ml.bolus?.interfaceIDs?.pumpId != null).toVisibility() + holder.binding.bolusInvalid.visibility = (ml.bolus?.isValid == true).not().toVisibility() + + // Carbs + holder.binding.carbsLayout.visibility = (ml.carbs != null && (ml.carbs?.isValid == true || binding.showInvalidated.isChecked)).toVisibility() + holder.binding.carbsDate.text = dateUtil.timeString(ml.carbs?.timestamp ?: 0L) + holder.binding.carbs.text = resourceHelper.gs(R.string.format_carbs, ml.carbs?.amount?.toInt() ?: 0) + holder.binding.carbsNs.visibility = (NSUpload.isIdValid(ml.carbs?.interfaceIDs?.nightscoutId)).toVisibility() + holder.binding.carbsPump.visibility = (ml.carbs?.interfaceIDs?.pumpId != null).toVisibility() + holder.binding.carbsInvalid.visibility = (ml.carbs?.isValid == true).not().toVisibility() + + holder.binding.bolusRemove.visibility = (ml.bolus?.isValid == true).toVisibility() + holder.binding.carbsRemove.visibility = (ml.carbs?.isValid == true).toVisibility() + holder.binding.bolusRemove.tag = ml + holder.binding.carbsRemove.tag = ml + holder.binding.calculation.tag = ml + } + + override fun getItemCount(): Int { + return mealLinks.size + } + + inner class MealLinkLoadedViewHolder internal constructor(view: View) : RecyclerView.ViewHolder(view) { + + val binding = TreatmentsMealLinkItemBinding.bind(view) + + init { + binding.calculation.setOnClickListener { + val mealLinkLoaded = it.tag as MealLinkLoaded + mealLinkLoaded.bolusCalculatorResult?.let { bolusCalculatorResult -> + WizardInfoDialog().also { wizardDialog -> + wizardDialog.setData(bolusCalculatorResult, mealLinkLoaded.therapyEvent?.note ?: "") + wizardDialog.show(childFragmentManager, "WizardInfoDialog") + } + } + } + binding.calculation.paintFlags = binding.calculation.paintFlags or Paint.UNDERLINE_TEXT_FLAG + binding.bolusRemove.setOnClickListener { + val mealLinkLoaded = it.tag as MealLinkLoaded? ?: return@setOnClickListener + activity?.let { activity -> + val text = resourceHelper.gs(R.string.configbuilder_insulin) + ": " + + resourceHelper.gs(R.string.formatinsulinunits, mealLinkLoaded.bolus!!.amount) + "\n" + + // resourceHelper.gs(R.string.carbs) + ": " + resourceHelper.gs(R.string.format_carbs, mealLinkLoaded.carbs.toInt()) + "\n" + + resourceHelper.gs(R.string.date) + ": " + dateUtil.dateAndTimeString(mealLinkLoaded.bolus!!.timestamp) + OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.removerecord), text, Runnable { + uel.log( + Action.TREATMENT_REMOVED, + ValueWithUnit(mealLinkLoaded.bolus!!.timestamp, Units.Timestamp), + ValueWithUnit(mealLinkLoaded.bolus!!.amount, Units.U) + // ValueWithUnit(mealLinkLoaded.carbs.toInt(), Units.G) + ) + disposable += repository.runTransactionForResult(InvalidateBolusTransaction(mealLinkLoaded.bolus!!.id)) + .subscribe({ + val id = mealLinkLoaded.bolus!!.interfaceIDs.nightscoutId + if (NSUpload.isIdValid(id)) nsUpload.removeCareportalEntryFromNS(id) + else uploadQueue.removeByMongoId("dbAdd", mealLinkLoaded.bolus!!.timestamp.toString()) + }, { + aapsLogger.error(LTag.DATATREATMENTS, "Error while invalidating bolus", it) + }) + }) + } + } + binding.bolusRemove.paintFlags = binding.bolusRemove.paintFlags or Paint.UNDERLINE_TEXT_FLAG + binding.carbsRemove.setOnClickListener { + val mealLinkLoaded = it.tag as MealLinkLoaded? ?: return@setOnClickListener + activity?.let { activity -> + val text = resourceHelper.gs(R.string.configbuilder_insulin) + ": " + + resourceHelper.gs(R.string.formatinsulinunits, mealLinkLoaded.bolus!!.amount) + "\n" + + // resourceHelper.gs(R.string.carbs) + ": " + resourceHelper.gs(R.string.format_carbs, mealLinkLoaded.carbs.toInt()) + "\n" + + resourceHelper.gs(R.string.date) + ": " + dateUtil.dateAndTimeString(mealLinkLoaded.bolus!!.timestamp) + OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.removerecord), text, Runnable { + uel.log( + Action.TREATMENT_REMOVED, + ValueWithUnit(mealLinkLoaded.bolus!!.timestamp, Units.Timestamp), + ValueWithUnit(mealLinkLoaded.bolus!!.amount, Units.U) + // ValueWithUnit(mealLinkLoaded.carbs.toInt(), Units.G) + ) + disposable += repository.runTransactionForResult(InvalidateCarbsTransaction(mealLinkLoaded.carbs!!.id)) + .subscribe({ + val id = mealLinkLoaded.carbs!!.interfaceIDs.nightscoutId + if (NSUpload.isIdValid(id)) nsUpload.removeCareportalEntryFromNS(id) + else uploadQueue.removeByMongoId("dbAdd", mealLinkLoaded.carbs!!.timestamp.toString()) + }, { + aapsLogger.error(LTag.DATATREATMENTS, "Error while invalidating carbs", it) + }) + }) + } + } + binding.carbsRemove.paintFlags = binding.carbsRemove.paintFlags or Paint.UNDERLINE_TEXT_FLAG + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.kt b/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.kt index d76c3759c4..c5d11f3627 100644 --- a/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.kt +++ b/app/src/main/java/info/nightscout/androidaps/queue/CommandQueue.kt @@ -13,7 +13,6 @@ import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.Profile import info.nightscout.androidaps.data.PumpEnactResult -import info.nightscout.androidaps.database.entities.Bolus import info.nightscout.androidaps.dialogs.BolusProgressDialog import info.nightscout.androidaps.events.EventBolusRequested import info.nightscout.androidaps.events.EventNewBasalProfile @@ -230,7 +229,7 @@ open class CommandQueue @Inject constructor( // returns true if command is queued @Synchronized override fun bolus(detailedBolusInfo: DetailedBolusInfo, callback: Callback?): Boolean { - var type = if (detailedBolusInfo.bolusType == Bolus.Type.SMB) CommandType.SMB_BOLUS else CommandType.BOLUS + var type = if (detailedBolusInfo.bolusType == DetailedBolusInfo.BolusType.SMB) CommandType.SMB_BOLUS else CommandType.BOLUS if (type == CommandType.SMB_BOLUS) { if (isRunning(CommandType.BOLUS) || isRunning(CommandType.SMB_BOLUS) || bolusInQueue()) { aapsLogger.debug(LTag.PUMPQUEUE, "Rejecting SMB since a bolus is queue/running") @@ -257,7 +256,7 @@ open class CommandQueue @Inject constructor( detailedBolusInfo.insulin = constraintChecker.applyBolusConstraints(Constraint(detailedBolusInfo.insulin)).value() detailedBolusInfo.carbs = constraintChecker.applyCarbsConstraints(Constraint(detailedBolusInfo.carbs.toInt())).value().toDouble() // add new command to queue - if (detailedBolusInfo.bolusType == Bolus.Type.SMB) { + if (detailedBolusInfo.bolusType == DetailedBolusInfo.BolusType.SMB) { add(CommandSMBBolus(injector, detailedBolusInfo, callback)) } else { add(CommandBolus(injector, detailedBolusInfo, callback, type)) diff --git a/app/src/main/java/info/nightscout/androidaps/utils/wizard/BolusWizard.kt b/app/src/main/java/info/nightscout/androidaps/utils/wizard/BolusWizard.kt index b7ec853ce1..079386be10 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/wizard/BolusWizard.kt +++ b/app/src/main/java/info/nightscout/androidaps/utils/wizard/BolusWizard.kt @@ -10,6 +10,7 @@ import info.nightscout.androidaps.R import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.Profile +import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.entities.BolusCalculatorResult import info.nightscout.androidaps.database.entities.TemporaryTarget import info.nightscout.androidaps.database.entities.TherapyEvent @@ -22,6 +23,7 @@ import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker +import info.nightscout.androidaps.plugins.general.nsclient.NSUpload import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin @@ -35,6 +37,8 @@ import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.extensions.formatColor import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.sharedPreferences.SP +import io.reactivex.disposables.CompositeDisposable +import io.reactivex.rxkotlin.plusAssign import java.util.* import javax.inject.Inject import kotlin.math.abs @@ -58,6 +62,10 @@ class BolusWizard @Inject constructor( @Inject lateinit var uel: UserEntryLogger @Inject lateinit var carbTimer: CarbTimer @Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider + @Inject lateinit var repository: AppRepository + @Inject lateinit var nsUpload: NSUpload + + private val disposable = CompositeDisposable() init { injector.androidInjector().inject(this) @@ -112,7 +120,7 @@ class BolusWizard @Inject constructor( var cob: Double = 0.0 var bg: Double = 0.0 private var correction: Double = 0.0 - private var percentageCorrection: Double = 0.0 + private var percentageCorrection: Int = 0 private var useBg: Boolean = false private var useCob: Boolean = false private var includeBolusIOB: Boolean = false @@ -132,7 +140,7 @@ class BolusWizard @Inject constructor( cob: Double, bg: Double, correction: Double, - percentageCorrection: Double = 100.0, + percentageCorrection: Int = 100, useBg: Boolean, useCob: Boolean, includeBolusIOB: Boolean, @@ -276,7 +284,7 @@ class BolusWizard @Inject constructor( val actions: LinkedList = LinkedList() if (insulinAfterConstraints > 0) { - val pct = if (percentageCorrection != 100.0) " (" + percentageCorrection.toInt() + "%)" else "" + val pct = if (percentageCorrection != 100) " ($percentageCorrection%)" else "" actions.add(resourceHelper.gs(R.string.bolus) + ": " + resourceHelper.gs(R.string.formatinsulinunits, insulinAfterConstraints).formatColor(resourceHelper, R.color.bolus) + pct) } if (carbs > 0 && !advisor) { @@ -328,16 +336,16 @@ class BolusWizard @Inject constructor( val confirmMessage = confirmMessageAfterConstraints(advisor = true) OKDialog.showConfirmation(ctx, resourceHelper.gs(R.string.boluswizard), confirmMessage, { DetailedBolusInfo().apply { - eventType = TherapyEvent.Type.CORRECTION_BOLUS + eventType = DetailedBolusInfo.EventType.CORRECTION_BOLUS insulin = insulinAfterConstraints carbs = 0.0 context = ctx mgdlGlucose = Profile.toMgdl(bg, profile.units) - glucoseType = TherapyEvent.MeterType.MANUAL + glucoseType = DetailedBolusInfo.MeterType.MANUAL carbTime = 0 bolusCalculatorResult = createBolusCalculatorResult() notes = this@BolusWizard.notes - uel.log(Action.BOLUS_ADVISOR, notes, ValueWithUnit(eventType, Units.TherapyEvent), ValueWithUnit(insulinAfterConstraints, Units.U)) + uel.log(Action.BOLUS_ADVISOR, notes, ValueWithUnit(eventType.toDBbEventType(), Units.TherapyEvent), ValueWithUnit(insulinAfterConstraints, Units.U)) if (insulin > 0) { commandQueue.bolus(this, object : Callback() { override fun run() { @@ -391,26 +399,44 @@ class BolusWizard @Inject constructor( } } DetailedBolusInfo().apply { - eventType = TherapyEvent.Type.BOLUS_WIZARD + eventType = DetailedBolusInfo.EventType.BOLUS_WIZARD insulin = insulinAfterConstraints carbs = this@BolusWizard.carbs.toDouble() context = ctx mgdlGlucose = Profile.toMgdl(bg, profile.units) - glucoseType = TherapyEvent.MeterType.MANUAL + glucoseType = DetailedBolusInfo.MeterType.MANUAL carbTime = this@BolusWizard.carbTime bolusCalculatorResult = createBolusCalculatorResult() notes = this@BolusWizard.notes - uel.log(Action.BOLUS, notes, ValueWithUnit(eventType, Units.TherapyEvent), ValueWithUnit(insulinAfterConstraints, Units.U), ValueWithUnit(this@BolusWizard.carbs, Units.G, this@BolusWizard.carbs != 0), ValueWithUnit(carbTime, Units.M, carbTime != 0)) if (insulin > 0 || pump.pumpDescription.storesCarbInfo) { commandQueue.bolus(this, object : Callback() { override fun run() { if (!result.success) { ErrorHelperActivity.runAlarm(ctx, result.comment, resourceHelper.gs(R.string.treatmentdeliveryerror), R.raw.boluserror) - } + } else + uel.log(Action.BOLUS, notes, + ValueWithUnit(eventType.toDBbEventType(), Units.TherapyEvent), + ValueWithUnit(insulinAfterConstraints, Units.U), + ValueWithUnit(this@BolusWizard.carbs, Units.G, this@BolusWizard.carbs != 0), + ValueWithUnit(carbTime, Units.M, carbTime != 0) + ) } }) } else { - activePlugin.activeTreatments.addToHistoryTreatment(this, false) + disposable += repository.runTransactionForResult(insertMealLinkTransaction()) + .subscribe({ result -> + result.inserted.forEach { inserted -> + uel.log(Action.BOLUS, notes, + ValueWithUnit(eventType.toDBbEventType(), Units.TherapyEvent), + ValueWithUnit(insulinAfterConstraints, Units.U), + ValueWithUnit(this@BolusWizard.carbs, Units.G, this@BolusWizard.carbs != 0), + ValueWithUnit(carbTime, Units.M, carbTime != 0) + ) + nsUpload.uploadMealLinkRecord(inserted) + } + }, { + aapsLogger.error(LTag.BGSOURCE, "Error while saving meal link", it) + }) } } if (useAlarm && carbs > 0 && carbTime > 0) { diff --git a/app/src/main/java/info/nightscout/androidaps/utils/wizard/QuickWizardEntry.kt b/app/src/main/java/info/nightscout/androidaps/utils/wizard/QuickWizardEntry.kt index 471bd0898a..efc2a371f3 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/wizard/QuickWizardEntry.kt +++ b/app/src/main/java/info/nightscout/androidaps/utils/wizard/QuickWizardEntry.kt @@ -125,7 +125,7 @@ class QuickWizardEntry @Inject constructor(private val injector: HasAndroidInjec } else if (useTrend() == NEGATIVE_ONLY && glucoseStatus != null && glucoseStatus.shortAvgDelta < 0) { trend = true } - val percentage = sp.getDouble(R.string.key_boluswizard_percentage, 100.0) + val percentage = sp.getInt(R.string.key_boluswizard_percentage, 100) return BolusWizard(injector).doCalc(profile, profileName, tempTarget, carbs(), cob, bg, 0.0, percentage, true, useCOB() == YES, bolusIOB, basalIOB, superBolus, useTempTarget() == YES, trend, false, "QuickWizard") } diff --git a/app/src/main/res/layout/treatments_careportal_fragment.xml b/app/src/main/res/layout/treatments_careportal_fragment.xml index 973d528718..438aa7c1de 100644 --- a/app/src/main/res/layout/treatments_careportal_fragment.xml +++ b/app/src/main/res/layout/treatments_careportal_fragment.xml @@ -44,7 +44,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" - android:contentDescription="@string/show_calculation" + android:contentDescription="@string/show_removed" app:srcCompat="@drawable/ic_visibility" /> diff --git a/app/src/main/res/layout/treatments_bolus_fragment.xml b/app/src/main/res/layout/treatments_meal_link_fragment.xml similarity index 57% rename from app/src/main/res/layout/treatments_bolus_fragment.xml rename to app/src/main/res/layout/treatments_meal_link_fragment.xml index e1690c3bcf..18db21e378 100644 --- a/app/src/main/res/layout/treatments_bolus_fragment.xml +++ b/app/src/main/res/layout/treatments_meal_link_fragment.xml @@ -1,53 +1,11 @@ - - - - - - - - - - - - + + + + @@ -31,15 +31,48 @@ android:id="@+id/date" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:paddingStart="5dp" - tools:ignore="RtlSymmetry" /> + android:layout_marginStart="5dp" + android:text="1.1.2000" + tools:ignore="HardcodedText,RtlSymmetry" /> + + + + + + + + @@ -48,16 +81,34 @@ + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 52a1be72c3..2fc3812925 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -978,6 +978,7 @@ BG Tools Show calcuation + Show removed Clear queue? All data in queue will be lost! xdripstatus_detailediob xdripstatus_showbgi diff --git a/app/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt b/app/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt index 97727ab5af..d104302084 100644 --- a/app/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt +++ b/app/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt @@ -57,7 +57,7 @@ class TestPumpPlugin(val injector: HasAndroidInjector) : PumpInterface { override fun cancelExtendedBolus(): PumpEnactResult = PumpEnactResult(injector).success(true) override fun getJSONStatus(profile: Profile, profileName: String, version: String): JSONObject = JSONObject() override fun manufacturer(): ManufacturerType = ManufacturerType.AndroidAPS - override fun model(): PumpType = PumpType.GenericAAPS + override fun model(): PumpType = PumpType.GENERIC_AAPS override fun serialNumber(): String = "1" override fun shortStatus(veryShort: Boolean): String = "" override val isFakingTempsByExtendedBoluses: Boolean = false diff --git a/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.kt b/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.kt index 192b107bef..985855aa5d 100644 --- a/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.kt @@ -51,7 +51,7 @@ import java.util.* */ @RunWith(PowerMockRunner::class) @PrepareForTest( - MainApp::class, ConfigBuilderPlugin::class, ConstraintChecker::class, SP::class, Context::class, + ConfigBuilderPlugin::class, ConstraintChecker::class, SP::class, Context::class, OpenAPSAMAPlugin::class, OpenAPSSMBPlugin::class, TreatmentsPlugin::class, TreatmentService::class, VirtualPumpPlugin::class, DetailedBolusInfoStorage::class, GlimpPlugin::class, Profiler::class, UserEntryLogger::class, IobCobCalculatorPlugin::class, LoggerUtils::class, AppRepository::class) diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/nsclient/NsClientReceiverDelegateTest.kt b/app/src/test/java/info/nightscout/androidaps/plugins/general/nsclient/NsClientReceiverDelegateTest.kt index 671178dfd9..74751fe5f5 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/nsclient/NsClientReceiverDelegateTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/nsclient/NsClientReceiverDelegateTest.kt @@ -1,7 +1,6 @@ package info.nightscout.androidaps.plugins.general.nsclient import android.content.Context -import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.R import info.nightscout.androidaps.TestBase import info.nightscout.androidaps.events.EventChargingState @@ -25,7 +24,7 @@ import org.powermock.core.classloader.annotations.PrepareForTest import org.powermock.modules.junit4.PowerMockRunner @RunWith(PowerMockRunner::class) -@PrepareForTest(MainApp::class, SP::class, Context::class) +@PrepareForTest(SP::class, Context::class) class NsClientReceiverDelegateTest : TestBase() { @Mock lateinit var context: Context diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt index ecc7b3374d..e3fefe6264 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt @@ -170,7 +170,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { `when`(virtualPumpPlugin.shortStatus(ArgumentMatchers.anyBoolean())).thenReturn("Virtual Pump") `when`(virtualPumpPlugin.isSuspended()).thenReturn(false) `when`(virtualPumpPlugin.pumpDescription).thenReturn(PumpDescription()) - `when`(virtualPumpPlugin.model()).thenReturn(PumpType.GenericAAPS) + `when`(virtualPumpPlugin.model()).thenReturn(PumpType.GENERIC_AAPS) `when`(treatmentsInterface.lastCalculationTreatments).thenReturn(IobTotal(0)) `when`(treatmentsInterface.lastCalculationTempBasals).thenReturn(IobTotal(0)) diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/pump/virtual/VirtualPumpPluginUTest.kt b/app/src/test/java/info/nightscout/androidaps/plugins/pump/virtual/VirtualPumpPluginUTest.kt index 1d3db18e1c..56a1b4904a 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/pump/virtual/VirtualPumpPluginUTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/plugins/pump/virtual/VirtualPumpPluginUTest.kt @@ -46,7 +46,7 @@ class VirtualPumpPluginUTest : TestBase() { fun refreshConfiguration() { PowerMockito.`when`(sp.getString(R.string.key_virtualpump_type, "Generic AAPS")).thenReturn("Accu-Chek Combo") virtualPumpPlugin.refreshConfiguration() - Assert.assertEquals(PumpType.AccuChekCombo, virtualPumpPlugin.pumpType) + Assert.assertEquals(PumpType.ACCU_CHEK_COMBO, virtualPumpPlugin.pumpType) } @Test @@ -55,6 +55,6 @@ class VirtualPumpPluginUTest : TestBase() { virtualPumpPlugin.refreshConfiguration() PowerMockito.`when`(sp.getString(R.string.key_virtualpump_type, "Generic AAPS")).thenReturn("Accu-Chek Combo") virtualPumpPlugin.refreshConfiguration() - Assert.assertEquals(PumpType.AccuChekCombo, virtualPumpPlugin.pumpType) + Assert.assertEquals(PumpType.ACCU_CHEK_COMBO, virtualPumpPlugin.pumpType) } } \ No newline at end of file diff --git a/automation/src/test/java/info/nightscout/androidaps/plugins/general/automation/TestPumpPlugin.kt b/automation/src/test/java/info/nightscout/androidaps/plugins/general/automation/TestPumpPlugin.kt index 478abe9484..b5c6682093 100644 --- a/automation/src/test/java/info/nightscout/androidaps/plugins/general/automation/TestPumpPlugin.kt +++ b/automation/src/test/java/info/nightscout/androidaps/plugins/general/automation/TestPumpPlugin.kt @@ -68,7 +68,7 @@ class TestPumpPlugin(pluginDescription: PluginDescription, override fun cancelExtendedBolus(): PumpEnactResult = PumpEnactResult(injector).success(true) override fun getJSONStatus(profile: Profile, profileName: String, version: String): JSONObject = JSONObject() override fun manufacturer(): ManufacturerType = ManufacturerType.AndroidAPS - override fun model(): PumpType = PumpType.GenericAAPS + override fun model(): PumpType = PumpType.GENERIC_AAPS override fun serialNumber(): String = "1" override fun shortStatus(veryShort: Boolean): String = "" override val isFakingTempsByExtendedBoluses: Boolean = false diff --git a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPlugin.java b/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPlugin.java index b57600527d..4b6981457a 100644 --- a/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPlugin.java +++ b/combo/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPlugin.java @@ -25,8 +25,6 @@ import info.nightscout.androidaps.combo.R; import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.PumpEnactResult; -import info.nightscout.androidaps.database.embedments.InterfaceIDs; -import info.nightscout.androidaps.database.entities.TherapyEvent; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TDD; import info.nightscout.androidaps.db.TemporaryBasal; @@ -160,7 +158,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr this.context = context; this.databaseHelper = databaseHelper; - pumpDescription.setPumpDescription(PumpType.AccuChekCombo); + pumpDescription.setPumpDescription(PumpType.ACCU_CHEK_COMBO); } @Override protected void onStart() { @@ -491,7 +489,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.INSTANCE; bolusingEvent.setT(new Treatment()); - bolusingEvent.getT().isSMB = detailedBolusInfo.getBolusType() == info.nightscout.androidaps.database.entities.Bolus.Type.SMB; + bolusingEvent.getT().isSMB = detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB; bolusingEvent.setPercent(100); rxBus.send(bolusingEvent); @@ -569,7 +567,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr } Treatment treatment = new Treatment(); - treatment.isSMB = detailedBolusInfo.getBolusType() == info.nightscout.androidaps.database.entities.Bolus.Type.SMB; + treatment.isSMB = detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB; EventOverviewBolusProgress.INSTANCE.setT(treatment); // start bolus delivery @@ -667,8 +665,8 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr */ private boolean addBolusToTreatments(DetailedBolusInfo detailedBolusInfo, Bolus lastPumpBolus) { DetailedBolusInfo bolusInfo = detailedBolusInfo.copy(); - bolusInfo.timestamp = calculateFakeBolusDate(lastPumpBolus); - bolusInfo.setPumpType(InterfaceIDs.PumpType.ACCU_CHEK_COMBO); + bolusInfo.setBolusTimestamp(calculateFakeBolusDate(lastPumpBolus)); + bolusInfo.setPumpType(PumpType.ACCU_CHEK_COMBO); bolusInfo.setPumpSerial(serialNumber()); bolusInfo.setBolusPumpId(bolusInfo.timestamp); bolusInfo.insulin = lastPumpBolus.amount; @@ -678,7 +676,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr DetailedBolusInfo carbInfo = new DetailedBolusInfo(); carbInfo.timestamp = bolusInfo.timestamp + bolusInfo.carbTime * 60L * 1000L; carbInfo.carbs = bolusInfo.carbs; - carbInfo.setPumpType(InterfaceIDs.PumpType.USER); + carbInfo.setPumpType(PumpType.USER); treatmentsPlugin.addToHistoryTreatment(carbInfo, true); // remove carbs from bolusInfo to not trigger any unwanted code paths in @@ -689,7 +687,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr treatmentsPlugin.addToHistoryTreatment(bolusInfo, true); } catch (Exception e) { getAapsLogger().error("Adding treatment record failed", e); - if (bolusInfo.getBolusType() == info.nightscout.androidaps.database.entities.Bolus.Type.SMB) { + if (bolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB) { Notification notification = new Notification(Notification.COMBO_PUMP_ALARM, getResourceHelper().gs(R.string.combo_error_updating_treatment_record), Notification.URGENT); rxBus.send(new EventNewNotification(notification)); } @@ -1156,12 +1154,12 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr boolean updated = false; for (Bolus pumpBolus : history.bolusHistory) { DetailedBolusInfo dbi = new DetailedBolusInfo(); - dbi.timestamp = calculateFakeBolusDate(pumpBolus); - dbi.setPumpType(InterfaceIDs.PumpType.ACCU_CHEK_COMBO); + dbi.setBolusTimestamp(calculateFakeBolusDate(pumpBolus)); + dbi.setPumpType(PumpType.ACCU_CHEK_COMBO); dbi.setPumpSerial(serialNumber()); dbi.setBolusPumpId(dbi.timestamp); dbi.insulin = pumpBolus.amount; - dbi.setEventType(TherapyEvent.Type.CORRECTION_BOLUS); + dbi.setEventType(DetailedBolusInfo.EventType.CORRECTION_BOLUS); if (treatmentsPlugin.addToHistoryTreatment(dbi, true)) { updated = true; } @@ -1311,7 +1309,7 @@ public class ComboPlugin extends PumpPluginBase implements PumpInterface, Constr @NonNull @Override public PumpType model() { - return PumpType.AccuChekCombo; + return PumpType.ACCU_CHEK_COMBO; } @NonNull @Override diff --git a/core/src/main/java/info/nightscout/androidaps/activities/TDDStatsActivity.kt b/core/src/main/java/info/nightscout/androidaps/activities/TDDStatsActivity.kt index ba650bace7..d1f21894c4 100644 --- a/core/src/main/java/info/nightscout/androidaps/activities/TDDStatsActivity.kt +++ b/core/src/main/java/info/nightscout/androidaps/activities/TDDStatsActivity.kt @@ -422,7 +422,7 @@ class TDDStatsActivity : NoSplashAppCompatActivity() { private fun isOldData(historyList: List): Boolean { val type = activePlugin.activePump.pumpDescription.pumpType - val startsYesterday = type == PumpType.DanaR || type == PumpType.DanaRS || type == PumpType.DanaRv2 || type == PumpType.DanaRKorean || type == PumpType.AccuChekInsight + val startsYesterday = type == PumpType.DANA_R || type == PumpType.DANA_RS || type == PumpType.DANA_RV2 || type == PumpType.DANA_R_KOREAN || type == PumpType.ACCU_CHEK_INSIGHT val df: DateFormat = SimpleDateFormat("dd.MM.", Locale.getDefault()) return historyList.size < 3 || df.format(Date(historyList[0].date)) != df.format(Date(System.currentTimeMillis() - if (startsYesterday) 1000 * 60 * 60 * 24 else 0)) } diff --git a/core/src/main/java/info/nightscout/androidaps/data/DetailedBolusInfo.kt b/core/src/main/java/info/nightscout/androidaps/data/DetailedBolusInfo.kt index bd88d789cc..d7f6b51689 100644 --- a/core/src/main/java/info/nightscout/androidaps/data/DetailedBolusInfo.kt +++ b/core/src/main/java/info/nightscout/androidaps/data/DetailedBolusInfo.kt @@ -2,11 +2,14 @@ package info.nightscout.androidaps.data import android.content.Context import com.google.gson.Gson -import info.nightscout.androidaps.database.embedments.InterfaceIDs import info.nightscout.androidaps.database.entities.Bolus import info.nightscout.androidaps.database.entities.BolusCalculatorResult import info.nightscout.androidaps.database.entities.Carbs +import info.nightscout.androidaps.database.entities.TemporaryBasal import info.nightscout.androidaps.database.entities.TherapyEvent +import info.nightscout.androidaps.database.transactions.InsertMealLinkTransaction +import info.nightscout.androidaps.plugins.pump.common.defs.PumpType +import info.nightscout.androidaps.utils.T class DetailedBolusInfo { @@ -23,36 +26,79 @@ class DetailedBolusInfo { // Prefilled info for storing to db var bolusCalculatorResult: BolusCalculatorResult? = null - var eventType = TherapyEvent.Type.MEAL_BOLUS + var eventType = EventType.MEAL_BOLUS var notes: String? = null var mgdlGlucose: Double? = null // Bg value in mgdl - var glucoseType: TherapyEvent.MeterType? = null // NS values: Manual, Finger, Sensor - var bolusType = Bolus.Type.NORMAL + var glucoseType: MeterType? = null // NS values: Manual, Finger, Sensor + var bolusType = BolusType.NORMAL + var carbsDuration = 0L // in milliseconds // Collected info from driver - var pumpType: InterfaceIDs.PumpType? = null // if == USER + var pumpType: PumpType? = null // if == USER var pumpSerial: String? = null var bolusPumpId: Long? = null + var bolusTimestamp: Long? = null var carbsPumpId: Long? = null + var carbsTimestamp: Long? = null + var superBolusTemporaryBasal: TemporaryBasal? = null - fun createTherapyEvent(): TherapyEvent? = - if (mgdlGlucose != null || notes != null) - TherapyEvent( - timestamp = timestamp, - type = TherapyEvent.Type.NOTE, - glucoseUnit = TherapyEvent.GlucoseUnit.MGDL, - note = notes, - glucose = mgdlGlucose, - glucoseType = glucoseType - ) - else null + enum class MeterType(val text: String) { + FINGER("Finger"), + SENSOR("Sensor"), + MANUAL("Manual"); + + fun toDbMeterType(): TherapyEvent.MeterType = + when (this) { + FINGER -> TherapyEvent.MeterType.FINGER + SENSOR -> TherapyEvent.MeterType.SENSOR + MANUAL -> TherapyEvent.MeterType.MANUAL + } + } + + enum class BolusType { + NORMAL, + SMB, + PRIMING; + + fun toDBbBolusType(): Bolus.Type = + when (this) { + NORMAL -> Bolus.Type.NORMAL + SMB -> Bolus.Type.SMB + PRIMING -> Bolus.Type.PRIMING + } + } + + enum class EventType { + MEAL_BOLUS, + BOLUS_WIZARD, + CORRECTION_BOLUS, + CARBS_CORRECTION; + + fun toDBbEventType(): TherapyEvent.Type = + when (this) { + MEAL_BOLUS -> TherapyEvent.Type.MEAL_BOLUS + BOLUS_WIZARD -> TherapyEvent.Type.BOLUS_WIZARD + CORRECTION_BOLUS -> TherapyEvent.Type.CORRECTION_BOLUS + CARBS_CORRECTION -> TherapyEvent.Type.CARBS_CORRECTION + } + } + + fun createTherapyEvent(): TherapyEvent = + TherapyEvent( + timestamp = timestamp, + type = eventType.toDBbEventType(), + glucoseUnit = TherapyEvent.GlucoseUnit.MGDL, + note = notes, + glucose = mgdlGlucose, + glucoseType = glucoseType?.toDbMeterType() + ) fun createBolus(): Bolus? = if (insulin != 0.0) Bolus( - timestamp = timestamp, + timestamp = bolusTimestamp ?: timestamp, amount = insulin, - type = bolusType, + type = bolusType.toDBbBolusType(), isBasalInsulin = false ) else null @@ -60,12 +106,26 @@ class DetailedBolusInfo { fun createCarbs(): Carbs? = if (carbs != 0.0) Carbs( - timestamp = timestamp, + timestamp = carbsTimestamp ?: T.mins(timestamp).msecs(), amount = carbs, - duration = 0 + duration = carbsDuration ) else null + fun insertMealLinkTransaction(): InsertMealLinkTransaction { + // For NS make sure timestamps of bolus and carbs are different to avoid unwanted deduplication + bolusTimestamp = bolusTimestamp ?: timestamp + carbsTimestamp = carbsTimestamp ?: timestamp + if (bolusTimestamp == carbsTimestamp) carbsTimestamp = carbsTimestamp!! + 1000 + return InsertMealLinkTransaction( + bolus = createBolus(), + carbs = createCarbs(), + bolusCalculatorResult = bolusCalculatorResult, + therapyEvent = createTherapyEvent(), + superBolusTemporaryBasal = superBolusTemporaryBasal + ) + } + fun toJsonString(): String = Gson().toJson(this) diff --git a/core/src/main/java/info/nightscout/androidaps/interfaces/InsulinInterface.kt b/core/src/main/java/info/nightscout/androidaps/interfaces/InsulinInterface.kt index 28a8ee8d0e..27397a2c83 100644 --- a/core/src/main/java/info/nightscout/androidaps/interfaces/InsulinInterface.kt +++ b/core/src/main/java/info/nightscout/androidaps/interfaces/InsulinInterface.kt @@ -1,6 +1,7 @@ package info.nightscout.androidaps.interfaces import info.nightscout.androidaps.data.Iob +import info.nightscout.androidaps.database.entities.Bolus import info.nightscout.androidaps.db.Treatment import org.json.JSONObject @@ -27,4 +28,5 @@ interface InsulinInterface : ConfigExportImportInterface{ val dia: Double fun iobCalcForTreatment(treatment: Treatment, time: Long, dia: Double): Iob + fun iobCalcForTreatment(bolus: Bolus, time: Long, dia: Double): Iob } \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/interfaces/PumpDescription.kt b/core/src/main/java/info/nightscout/androidaps/interfaces/PumpDescription.kt index 26f42a646d..0aec8d7484 100644 --- a/core/src/main/java/info/nightscout/androidaps/interfaces/PumpDescription.kt +++ b/core/src/main/java/info/nightscout/androidaps/interfaces/PumpDescription.kt @@ -10,7 +10,7 @@ class PumpDescription() { setPumpDescription(pumpType) } - var pumpType = PumpType.GenericAAPS + var pumpType = PumpType.GENERIC_AAPS var isBolusCapable = false var bolusStep = 0.0 var isExtendedBolusCapable = false @@ -72,29 +72,27 @@ class PumpDescription() { fun setPumpDescription(pumpType: PumpType) { resetSettings() this.pumpType = pumpType - val pumpCapability = pumpType.pumpCapability + val pumpCapability = pumpType.pumpCapability ?: return isBolusCapable = pumpCapability.hasCapability(PumpCapability.Bolus) bolusStep = pumpType.bolusSize isExtendedBolusCapable = pumpCapability.hasCapability(PumpCapability.ExtendedBolus) - extendedBolusStep = pumpType.extendedBolusSettings.step - extendedBolusDurationStep = pumpType.extendedBolusSettings.durationStep.toDouble() - extendedBolusMaxDuration = pumpType.extendedBolusSettings.maxDuration.toDouble() + pumpType.extendedBolusSettings?.step?.let { extendedBolusStep = it } + pumpType.extendedBolusSettings?.durationStep?.let { extendedBolusDurationStep = it.toDouble() } + pumpType.extendedBolusSettings?.maxDuration?.let { extendedBolusMaxDuration = it.toDouble() } isTempBasalCapable = pumpCapability.hasCapability(PumpCapability.TempBasal) if (pumpType.pumpTempBasalType == PumpTempBasalType.Percent) { tempBasalStyle = PERCENT - maxTempPercent = pumpType.tbrSettings.maxDose.toInt() - tempPercentStep = pumpType.tbrSettings.step.toInt() + pumpType.tbrSettings?.maxDose?.let { maxTempPercent = it.toInt() } + pumpType.tbrSettings?.step?.let { tempPercentStep = it.toInt() } } else { tempBasalStyle = ABSOLUTE - maxTempAbsolute = pumpType.tbrSettings.maxDose - tempAbsoluteStep = pumpType.tbrSettings.step + pumpType.tbrSettings?.maxDose?.let { maxTempAbsolute = it } + pumpType.tbrSettings?.step?.let { tempAbsoluteStep = it } } - tempDurationStep = pumpType.tbrSettings.durationStep - tempMaxDuration = pumpType.tbrSettings.maxDuration - tempDurationStep15mAllowed = pumpType.specialBasalDurations - .hasCapability(PumpCapability.BasalRate_Duration15minAllowed) - tempDurationStep30mAllowed = pumpType.specialBasalDurations - .hasCapability(PumpCapability.BasalRate_Duration30minAllowed) + pumpType.tbrSettings?.durationStep?.let { tempDurationStep = it } + pumpType.tbrSettings?.maxDuration?.let { tempMaxDuration = it } + pumpType.specialBasalDurations?.hasCapability(PumpCapability.BasalRate_Duration15minAllowed)?.let { tempDurationStep15mAllowed = it } + pumpType.specialBasalDurations?.hasCapability(PumpCapability.BasalRate_Duration30minAllowed)?.let { tempDurationStep30mAllowed = it } isSetBasalProfileCapable = pumpCapability.hasCapability(PumpCapability.BasalProfileSet) basalStep = pumpType.baseBasalStep basalMinimumRate = pumpType.baseBasalMinValue diff --git a/core/src/main/java/info/nightscout/androidaps/logging/UserEntryLogger.kt b/core/src/main/java/info/nightscout/androidaps/logging/UserEntryLogger.kt index 96a02cf3df..ae07b61532 100644 --- a/core/src/main/java/info/nightscout/androidaps/logging/UserEntryLogger.kt +++ b/core/src/main/java/info/nightscout/androidaps/logging/UserEntryLogger.kt @@ -1,8 +1,8 @@ package info.nightscout.androidaps.logging -import info.nightscout.androidaps.Constants import info.nightscout.androidaps.database.AppRepository -import info.nightscout.androidaps.database.entities.UserEntry.* +import info.nightscout.androidaps.database.entities.UserEntry.Action +import info.nightscout.androidaps.database.entities.UserEntry.ValueWithUnit import info.nightscout.androidaps.database.transactions.UserEntryTransaction import info.nightscout.androidaps.utils.rx.AapsSchedulers import io.reactivex.disposables.CompositeDisposable @@ -38,9 +38,9 @@ class UserEntryLogger @Inject constructor( ) } - fun log(action: Action, vararg listvalues: ValueWithUnit) { + fun log(action: Action, vararg listValues: ValueWithUnit) { val values = mutableListOf() - for (v in listvalues){ + for (v in listValues){ if (v.condition) values.add(v) } compositeDisposable += repository.runTransaction(UserEntryTransaction( diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/aps/loop/APSResult.kt b/core/src/main/java/info/nightscout/androidaps/plugins/aps/loop/APSResult.kt index b7f1048464..3a7e187dd7 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/aps/loop/APSResult.kt +++ b/core/src/main/java/info/nightscout/androidaps/plugins/aps/loop/APSResult.kt @@ -338,7 +338,7 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) { } // always report hightemp if (pump.pumpDescription.tempBasalStyle == PumpDescription.PERCENT) { - val pumpLimit = pump.pumpDescription.pumpType.tbrSettings.maxDose + val pumpLimit = pump.pumpDescription.pumpType.tbrSettings?.maxDose ?: 0.0 if (percent.toDouble() == pumpLimit) { aapsLogger.debug(LTag.APS, "TRUE: Pump limit") return true @@ -374,7 +374,7 @@ open class APSResult @Inject constructor(val injector: HasAndroidInjector) { } // always report hightemp if (pump.pumpDescription.tempBasalStyle == PumpDescription.ABSOLUTE) { - val pumpLimit = pump.pumpDescription.pumpType.tbrSettings.maxDose + val pumpLimit = pump.pumpDescription.pumpType.tbrSettings?.maxDose ?: 0.0 if (rate == pumpLimit) { aapsLogger.debug(LTag.APS, "TRUE: Pump limit") return true diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/configBuilder/RunningConfiguration.kt b/core/src/main/java/info/nightscout/androidaps/plugins/configBuilder/RunningConfiguration.kt index bfc9014b0b..269be3f30b 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/configBuilder/RunningConfiguration.kt +++ b/core/src/main/java/info/nightscout/androidaps/plugins/configBuilder/RunningConfiguration.kt @@ -80,7 +80,7 @@ class RunningConfiguration @Inject constructor( } if (configuration.has("pump")) { - val pumpType = JsonHelper.safeGetString(configuration, "pump", PumpType.GenericAAPS.description) + val pumpType = JsonHelper.safeGetString(configuration, "pump", PumpType.GENERIC_AAPS.description) sp.putString(R.string.key_virtualpump_type, pumpType) activePlugin.activePump.pumpDescription.setPumpDescription(PumpType.getByDescription(pumpType)) aapsLogger.debug(LTag.CORE, "Changing pump type to $pumpType") diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSUpload.java b/core/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSUpload.java index da5cb1d90a..149e3e09e2 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSUpload.java +++ b/core/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/NSUpload.java @@ -4,6 +4,8 @@ import android.os.Build; import androidx.annotation.Nullable; +import com.google.gson.Gson; + import org.json.JSONException; import org.json.JSONObject; @@ -17,7 +19,10 @@ import info.nightscout.androidaps.core.R; import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.database.entities.Bolus; +import info.nightscout.androidaps.database.entities.Carbs; import info.nightscout.androidaps.database.entities.GlucoseValue; +import info.nightscout.androidaps.database.entities.MealLinkLoaded; import info.nightscout.androidaps.database.entities.TemporaryTarget; import info.nightscout.androidaps.database.entities.TherapyEvent; import info.nightscout.androidaps.db.DbRequest; @@ -245,6 +250,7 @@ public class NSUpload { } public void uploadTreatmentRecord(DetailedBolusInfo detailedBolusInfo) { + throw new IllegalStateException("DO NOT USE"); /* JSONObject data = new JSONObject(); try { @@ -271,10 +277,60 @@ public class NSUpload { aapsLogger.error("Unhandled exception", e); } uploadCareportalEntryToNS(data, detailedBolusInfo.timestamp); - */ } + public void uploadMealLinkRecord(MealLinkLoaded mealLinkLoaded) { + Bolus bolus = mealLinkLoaded.getBolus(); + Carbs carbs = mealLinkLoaded.getCarbs(); + TherapyEvent therapyEvent = mealLinkLoaded.getTherapyEvent(); + if (bolus != null && therapyEvent != null && bolus.getAmount() > 0) { + try { + JSONObject data = new JSONObject(); + data.put("eventType", therapyEvent.getType().getText()); + data.put("insulin", bolus.getAmount()); + data.put("created_at", DateUtil.toISOString(bolus.getTimestamp())); + data.put("date", bolus.getTimestamp()); + data.put("isSMB", bolus.getType() == Bolus.Type.SMB); + if (bolus.getInterfaceIDs().getPumpId() != null) + data.put("pumpId", bolus.getInterfaceIDs().getPumpId()); + if (therapyEvent.getGlucose() != null) + data.put("glucose", therapyEvent.getGlucose()); + if (therapyEvent.getGlucoseType() != null) + data.put("glucoseType", therapyEvent.getGlucoseType().getText()); + if (mealLinkLoaded.getBolusCalculatorResult() != null) + data.put("bolusCalc", new Gson().toJson(mealLinkLoaded.getBolusCalculatorResult())); + if (therapyEvent.getNote() != null) + data.put("notes", therapyEvent.getNote()); + uploadCareportalEntryToNS(data, bolus.getTimestamp()); + } catch (JSONException e) { + e.printStackTrace(); + } + } + if (carbs != null && therapyEvent != null && carbs.getAmount() > 0) { + try { + JSONObject data = new JSONObject(); + data.put("eventType", therapyEvent.getType().getText()); + data.put("carbs", carbs.getAmount()); + data.put("created_at", DateUtil.toISOString(carbs.getTimestamp())); + data.put("date", carbs.getTimestamp()); + if (carbs.getDuration() != 0) + data.put("duration", carbs.getDuration()); + if (carbs.getInterfaceIDs().getPumpId() != null) + data.put("pumpId", carbs.getInterfaceIDs().getPumpId()); + if (therapyEvent.getGlucose() != null) + data.put("glucose", therapyEvent.getGlucose()); + if (therapyEvent.getGlucoseType() != null) + data.put("glucoseType", therapyEvent.getGlucoseType().getText()); + if (therapyEvent.getNote() != null) + data.put("notes", therapyEvent.getNote()); + uploadCareportalEntryToNS(data, carbs.getTimestamp()); + } catch (JSONException e) { + e.printStackTrace(); + } + } + } + public void uploadProfileSwitch(ProfileSwitch profileSwitch, long nsClientId) { try { JSONObject data = getJson(profileSwitch); diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/PumpPluginAbstract.java b/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/PumpPluginAbstract.java index 419fe0743d..ad817d39f6 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/PumpPluginAbstract.java +++ b/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/PumpPluginAbstract.java @@ -16,7 +16,6 @@ import info.nightscout.androidaps.core.R; import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.PumpEnactResult; -import info.nightscout.androidaps.database.entities.Bolus; import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.db.Treatment; @@ -420,7 +419,7 @@ public abstract class PumpPluginAbstract extends PumpPluginBase implements PumpI EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.INSTANCE; bolusingEvent.setT(new Treatment()); - bolusingEvent.getT().isSMB = detailedBolusInfo.getBolusType() == Bolus.Type.SMB; + bolusingEvent.getT().isSMB = detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB; bolusingEvent.setPercent(100); rxBus.send(bolusingEvent); diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/data/DoseSettings.java b/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/data/DoseSettings.java deleted file mode 100644 index b617e5e3ee..0000000000 --- a/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/data/DoseSettings.java +++ /dev/null @@ -1,49 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.common.data; - -/** - * Created by andy on 02/05/2018. - */ - -public class DoseSettings { - - private final double step; - private final int durationStep; - private final int maxDuration; - private final double minDose; - private final Double maxDose; - - public DoseSettings(double step, int durationStep, int maxDuration, double minDose, Double maxDose) - { - this.step = step; - this.durationStep = durationStep; - this.maxDuration = maxDuration; - this.minDose = minDose; - this.maxDose = maxDose; - } - - public DoseSettings(double step, int durationStep, int maxDuration, double minDose) - { - this(step, durationStep, maxDuration, minDose, Double.MAX_VALUE); - } - - - public double getStep() { - return step; - } - - public int getDurationStep() { - return durationStep; - } - - public int getMaxDuration() { - return maxDuration; - } - - public double getMinDose() { - return minDose; - } - - public Double getMaxDose() { - return maxDose; - } -} diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/data/DoseSettings.kt b/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/data/DoseSettings.kt new file mode 100644 index 0000000000..90e25a7e37 --- /dev/null +++ b/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/data/DoseSettings.kt @@ -0,0 +1,3 @@ +package info.nightscout.androidaps.plugins.pump.common.data + +class DoseSettings constructor(val step: Double, val durationStep: Int, val maxDuration: Int, val minDose: Double, val maxDose: Double = Double.MAX_VALUE) \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpCapability.java b/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpCapability.java deleted file mode 100644 index 183cfbe8d9..0000000000 --- a/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpCapability.java +++ /dev/null @@ -1,69 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.common.defs; - -/** - * Created by andy on 03/05/2018. - */ - -public enum PumpCapability { - - Bolus, // isBolusCapable - ExtendedBolus, // isExtendedBolusCapable - 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, 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), // - YpsomedCapabilities(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill, ReplaceBattery, TDD, ManualTDDLoad), - - // BasalRates (separately grouped) - BasalRate_Duration15minAllowed, // - BasalRate_Duration30minAllowed, // - BasalRate_Duration15and30minAllowed(BasalRate_Duration15minAllowed, BasalRate_Duration30minAllowed), // - BasalRate_Duration15and30minNotAllowed, // - ; - - PumpCapability[] children; - - - PumpCapability() { - } - - - PumpCapability(PumpCapability... children) { - this.children = children; - } - - - public boolean hasCapability(PumpCapability capability) { - // we can only check presense of simple capabilities - if (capability.children != null) - return false; - - if (this == capability) - return true; - - if (this.children != null) { - for (PumpCapability child : children) { - if (child == capability) - return true; - } - - return false; - } else - return false; - } - - -} diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpCapability.kt b/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpCapability.kt new file mode 100644 index 0000000000..5276dbabb6 --- /dev/null +++ b/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpCapability.kt @@ -0,0 +1,44 @@ +package info.nightscout.androidaps.plugins.pump.common.defs + +import info.nightscout.androidaps.plugins.pump.common.defs.PumpCapability + +/** + * Created by andy on 03/05/2018. + */ +enum class PumpCapability { + + Bolus, // isBolusCapable + ExtendedBolus, // isExtendedBolusCapable + TempBasal, // isTempBasalCapable + BasalProfileSet, // isSetBasalProfileCapable + Refill, // isRefillingCapable + ReplaceBattery, // isBatteryReplaceable + StoreCarbInfo, // storesCarbInfo + TDD, // supportsTDDs + ManualTDDLoad, // needsManualTDDLoad + BasalRate30min, // is30minBasalRatesCapable + + // grouped by pump + MDI(arrayOf(Bolus)), + VirtualPumpCapabilities(arrayOf(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill, ReplaceBattery)), + ComboCapabilities(arrayOf(Bolus, TempBasal, BasalProfileSet, Refill, ReplaceBattery, TDD, ManualTDDLoad)), + DanaCapabilities(arrayOf(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill, ReplaceBattery, TDD, ManualTDDLoad)), + DanaWithHistoryCapabilities(arrayOf(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill, ReplaceBattery, StoreCarbInfo, TDD, ManualTDDLoad)), + InsightCapabilities(arrayOf(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill, ReplaceBattery, TDD, BasalRate30min)), + MedtronicCapabilities(arrayOf(Bolus, TempBasal, BasalProfileSet, Refill, ReplaceBattery, TDD)), + OmnipodCapabilities(arrayOf(Bolus, TempBasal, BasalProfileSet, BasalRate30min)), + YpsomedCapabilities(arrayOf(Bolus, ExtendedBolus, TempBasal, BasalProfileSet, Refill, ReplaceBattery, TDD, ManualTDDLoad)), // BasalRates (separately grouped) + BasalRate_Duration15minAllowed, + BasalRate_Duration30minAllowed, + BasalRate_Duration15and30minAllowed(arrayOf(BasalRate_Duration15minAllowed, BasalRate_Duration30minAllowed)), + BasalRate_Duration15and30minNotAllowed; + + var children: ArrayList = ArrayList() + + constructor() { children.add(this)} + constructor(list: Array) { + children.addAll(list) + } + + fun hasCapability(capability: PumpCapability): Boolean = children.contains(capability) +} \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpType.java b/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpType.java deleted file mode 100644 index 670ec3fae1..0000000000 --- a/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpType.java +++ /dev/null @@ -1,481 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.common.defs; - - -import java.util.HashMap; -import java.util.Map; - -import info.nightscout.androidaps.core.R; -import info.nightscout.androidaps.plugins.common.ManufacturerType; -import info.nightscout.androidaps.plugins.pump.common.data.DoseSettings; -import info.nightscout.androidaps.utils.Round; -import info.nightscout.androidaps.utils.resources.ResourceHelper; - - -/** - * Created by andy on 02/05/2018. - *

- * Most of this defintions is intended for VirtualPump only, but they can be used by other plugins. - */ - -public enum PumpType { - - GenericAAPS("Generic AAPS", ManufacturerType.AndroidAPS, "VirutalPump", 0.1d, null, // - new DoseSettings(0.05d, 30, 8 * 60, 0.05d), // - PumpTempBasalType.Percent, // - new DoseSettings(10, 30, 24 * 60, 0d, 500d), PumpCapability.BasalRate_Duration15and30minAllowed, // - 0.01d, 0.01d, null, PumpCapability.VirtualPumpCapabilities), // - - // Cellnovo - - Cellnovo1("Cellnovo", ManufacturerType.Cellnovo, "Cellnovo", 0.05d, null, // - new DoseSettings(0.05d, 30, 24 * 60, 1d, null), - PumpTempBasalType.Percent, - new DoseSettings(5, 30, 24 * 60, 0d, 200d), PumpCapability.BasalRate_Duration30minAllowed, // - 0.05d, 0.05d, null, PumpCapability.VirtualPumpCapabilities), // - - // Accu-Chek - - AccuChekCombo("Accu-Chek Combo", ManufacturerType.Roche, "Combo", 0.1d, null, // - new DoseSettings(0.1d, 15, 12 * 60, 0.1d), // - PumpTempBasalType.Percent, - new DoseSettings(10, 15, 12 * 60, 0d, 500d), PumpCapability.BasalRate_Duration15and30minAllowed, // - 0.01d, 0.01d, DoseStepSize.ComboBasal, PumpCapability.ComboCapabilities), // - - AccuChekSpirit("Accu-Chek Spirit", ManufacturerType.Roche, "Spirit", 0.1d, null, // - new DoseSettings(0.1d, 15, 12 * 60, 0.1d), // - PumpTempBasalType.Percent, - new DoseSettings(10, 15, 12 * 60, 0d, 500d), PumpCapability.BasalRate_Duration15and30minAllowed, // - 0.01d, 0.1d, null, PumpCapability.VirtualPumpCapabilities), // - - AccuChekInsight("Accu-Chek Insight", ManufacturerType.Roche, "Insight", 0.05d, DoseStepSize.InsightBolus, // - new DoseSettings(0.05d, 15, 24 * 60, 0.05d), // - PumpTempBasalType.Percent, - new DoseSettings(10, 15, 24 * 60, 0d, 250d), PumpCapability.BasalRate_Duration15and30minAllowed, // - 0.02d, 0.01d, null, PumpCapability.InsightCapabilities), // - - AccuChekInsightBluetooth("Accu-Chek Insight", ManufacturerType.Roche, "Insight", 0.01d, null, // - new DoseSettings(0.01d, 15, 24 * 60, 0.05d), // - PumpTempBasalType.Percent, - new DoseSettings(10, 15, 24 * 60, 0d, 250d), PumpCapability.BasalRate_Duration15and30minAllowed, // - 0.02d, null, 0.01d, DoseStepSize.InsightBolus, PumpCapability.InsightCapabilities), // - - AccuChekSolo("Accu-Chek Solo", ManufacturerType.Roche, "Solo", 0.01d, null, // - new DoseSettings(0.01d, 15, 24 * 60, 0.05d), // - PumpTempBasalType.Percent, - new DoseSettings(10, 15, 24 * 60, 0d, 250d), PumpCapability.BasalRate_Duration15and30minAllowed, // - 0.02d, null, 0.01d, DoseStepSize.InsightBolus, PumpCapability.InsightCapabilities), // - - - // Animas - AnimasVibe("Animas Vibe", ManufacturerType.Animas, "Vibe", 0.05d, null, // AnimasBolus? - new DoseSettings(0.05d, 30, 12 * 60, 0.05d), // - PumpTempBasalType.Percent, // - new DoseSettings(10, 30, 24 * 60, 0d, 300d), PumpCapability.BasalRate_Duration30minAllowed, // - 0.025d, 5d, 0d, null, PumpCapability.VirtualPumpCapabilities), // - - AnimasPing("Animas Ping", "Ping", AnimasVibe), - - // Dana - DanaR("DanaR", ManufacturerType.Sooil, "DanaR", 0.05d, null, // - new DoseSettings(0.05d, 30, 8 * 60, 0.05d), // - PumpTempBasalType.Percent, // - new DoseSettings(10d, 60, 24 * 60, 0d, 200d), PumpCapability.BasalRate_Duration15and30minNotAllowed, // - 0.04d, 0.01d, null, PumpCapability.DanaCapabilities), - - DanaRKorean("DanaR Korean", ManufacturerType.Sooil, "DanaRKorean", 0.05d, null, // - new DoseSettings(0.05d, 30, 8 * 60, 0.05d), // - PumpTempBasalType.Percent, // - new DoseSettings(10d, 60, 24 * 60, 0d, 200d), PumpCapability.BasalRate_Duration15and30minNotAllowed, // - 0.1d, 0.01d, null, PumpCapability.DanaCapabilities), - - DanaRS("DanaRS", ManufacturerType.Sooil, "DanaRS", 0.05d, null, // - new DoseSettings(0.05d, 30, 8 * 60, 0.05d), // - PumpTempBasalType.Percent, // - new DoseSettings(10d, 60, 24 * 60, 0d, 200d), PumpCapability.BasalRate_Duration15and30minAllowed, // - 0.04d, 0.01d, null, PumpCapability.DanaWithHistoryCapabilities), - - DanaRv2("DanaRv2", "DanaRv2", DanaRS), - - - // Insulet - Omnipod_Eros("Omnipod", ManufacturerType.Insulet, "Eros", 0.05d, null, // - new DoseSettings(0.05d, 30, 8 * 60, 0.05d), // - PumpTempBasalType.Absolute, // - new DoseSettings(0.05d, 30, 12 * 60, 0d, 30.0d), PumpCapability.BasalRate_Duration30minAllowed, // - 0.05d, null, 0.05d, null, PumpCapability.OmnipodCapabilities, true), - - Omnipod_Dash("Omnipod", ManufacturerType.Insulet, "Dash", 0.05d, null, // - new DoseSettings(0.05d, 30, 8 * 60, 0.05d), // - PumpTempBasalType.Absolute, // - new DoseSettings(0.05d, 30, 12 * 60, 0d, 30.0d), PumpCapability.BasalRate_Duration30minAllowed, // - 0.05d, null, 0.05d, null, PumpCapability.OmnipodCapabilities, false), - - - // Medtronic - Medtronic_512_712("Medtronic 512/712", ManufacturerType.Medtronic, "512/712", 0.1d, null, // - new DoseSettings(0.05d, 30, 8 * 60, 0.05d), // - PumpTempBasalType.Absolute, // - new DoseSettings(0.05d, 30, 24 * 60, 0d, 35d), PumpCapability.BasalRate_Duration30minAllowed, // - 0.05d, 0.05d, null, PumpCapability.MedtronicCapabilities), // - - Medtronic_515_715("Medtronic 515/715", "515/715", Medtronic_512_712), - Medtronic_522_722("Medtronic 522/722", "522/722", Medtronic_512_712), - - Medtronic_523_723_Revel("Medtronic 523/723 (Revel)", ManufacturerType.Medtronic, "523/723 (Revel)", 0.05d, null, // - new DoseSettings(0.05d, 30, 8 * 60, 0.05d), // - PumpTempBasalType.Absolute, // - new DoseSettings(0.05d, 30, 24 * 60, 0d, 35d), PumpCapability.BasalRate_Duration30minAllowed, // - 0.025d, 0.025d, DoseStepSize.MedtronicVeoBasal, PumpCapability.MedtronicCapabilities), // - - Medtronic_554_754_Veo("Medtronic 554/754 (Veo)", "554/754 (Veo)", Medtronic_523_723_Revel), // TODO - - Medtronic_640G("Medtronic 640G", ManufacturerType.Medtronic, "640G", 0.025d, null, // - new DoseSettings(0.05d, 30, 8 * 60, 0.05d), // - PumpTempBasalType.Absolute, // - new DoseSettings(0.05d, 30, 24 * 60, 0d, 35d), PumpCapability.BasalRate_Duration30minAllowed, // - 0.025d, 0.025d, DoseStepSize.MedtronicVeoBasal, PumpCapability.VirtualPumpCapabilities), // - - // Tandem - TandemTSlim("Tandem t:slim", ManufacturerType.Tandem, "t:slim", 0.01d, null, // - new DoseSettings(0.01d, 15, 8 * 60, 0.4d), - PumpTempBasalType.Percent, - new DoseSettings(1, 15, 8 * 60, 0d, 250d), PumpCapability.BasalRate_Duration15and30minAllowed, // - 0.1d, 0.001d, null, PumpCapability.VirtualPumpCapabilities), - - TandemTFlex("Tandem t:flex", "t:flex", TandemTSlim), // - TandemTSlimG4("Tandem t:slim G4", "t:slim G4", TandemTSlim), // - TandemTSlimX2("Tandem t:slim X2", "t:slim X2", TandemTSlim), // - - // Ypsomed/myLife - YpsoPump("YpsoPump", ManufacturerType.Ypsomed, "Ypsopump", 0.1d, null, // - new DoseSettings(0.1d, 15, 12 * 60, 0.1d), // - PumpTempBasalType.Percent, - new DoseSettings(1, 15, 24 * 60, 0d, 500d), PumpCapability.BasalRate_Duration15and30minAllowed, // - 0.02d, 40.0d, 0.01d, DoseStepSize.YpsopumpBasal, PumpCapability.YpsomedCapabilities), - - - // MDI - MDI("MDI", ManufacturerType.AndroidAPS, "MDI"); - - - private final String description; - private ManufacturerType manufacturer; - private String model; - private double bolusSize; - private DoseStepSize specialBolusSize; - private DoseSettings extendedBolusSettings; - private PumpTempBasalType pumpTempBasalType; - private DoseSettings tbrSettings; - private PumpCapability specialBasalDurations; - private double baseBasalMinValue; // - private Double baseBasalMaxValue; - private double baseBasalStep; // - private DoseStepSize baseBasalSpecialSteps; // - private PumpCapability pumpCapability; - private boolean hasCustomUnreachableAlertCheck; - - private PumpType parent; - private static final Map mapByDescription; - - static { - mapByDescription = new HashMap<>(); - - for (PumpType pumpType : values()) { - mapByDescription.put(pumpType.getDescription(), pumpType); - } - } - - - PumpType(String description, String model, PumpType parent) { - this.description = description; - this.parent = parent; - this.model = model; - } - - - PumpType(String description, ManufacturerType manufacturer, String model) { - this.description = description; - this.manufacturer = manufacturer; - this.model = model; - } - - - PumpType(String description, String model, PumpType parent, PumpCapability pumpCapability) { - this.description = description; - this.parent = parent; - this.pumpCapability = pumpCapability; - parent.model = model; - } - - PumpType(String description, - ManufacturerType manufacturer, - String model, - double bolusSize, - DoseStepSize specialBolusSize, // - DoseSettings extendedBolusSettings, // - PumpTempBasalType pumpTempBasalType, - DoseSettings tbrSettings, - PumpCapability specialBasalDurations, // - double baseBasalMinValue, - double baseBasalStep, - DoseStepSize baseBasalSpecialSteps, - PumpCapability pumpCapability) { - this(description, manufacturer, model, bolusSize, specialBolusSize, extendedBolusSettings, pumpTempBasalType, tbrSettings, specialBasalDurations, baseBasalMinValue, null, baseBasalStep, baseBasalSpecialSteps, pumpCapability); - } - - PumpType(String description, - ManufacturerType manufacturer, - String model, - double bolusSize, - DoseStepSize specialBolusSize, // - DoseSettings extendedBolusSettings, // - PumpTempBasalType pumpTempBasalType, - DoseSettings tbrSettings, - PumpCapability specialBasalDurations, // - double baseBasalMinValue, - Double baseBasalMaxValue, - double baseBasalStep, - DoseStepSize baseBasalSpecialSteps, - PumpCapability pumpCapability) { - this(description, manufacturer, model, bolusSize, specialBolusSize, extendedBolusSettings, pumpTempBasalType, - tbrSettings, specialBasalDurations, baseBasalMinValue, null, baseBasalStep, - baseBasalSpecialSteps, pumpCapability, false); - } - - - PumpType(String description, - ManufacturerType manufacturer, - String model, - double bolusSize, - DoseStepSize specialBolusSize, // - DoseSettings extendedBolusSettings, // - PumpTempBasalType pumpTempBasalType, - DoseSettings tbrSettings, - PumpCapability specialBasalDurations, // - double baseBasalMinValue, - Double baseBasalMaxValue, - double baseBasalStep, - DoseStepSize baseBasalSpecialSteps, // - PumpCapability pumpCapability, - boolean hasCustomUnreachableAlertCheck) { - this.description = description; - this.manufacturer = manufacturer; - this.model = model; - this.bolusSize = bolusSize; - this.specialBolusSize = specialBolusSize; - this.extendedBolusSettings = extendedBolusSettings; - this.pumpTempBasalType = pumpTempBasalType; - this.tbrSettings = tbrSettings; - this.specialBasalDurations = specialBasalDurations; - this.baseBasalMinValue = baseBasalMinValue; - this.baseBasalMaxValue = baseBasalMaxValue; - this.baseBasalStep = baseBasalStep; - this.baseBasalSpecialSteps = baseBasalSpecialSteps; - this.pumpCapability = pumpCapability; - this.hasCustomUnreachableAlertCheck = hasCustomUnreachableAlertCheck; - } - - public boolean getHasCustomUnreachableAlertCheck() { - return hasCustomUnreachableAlertCheck; - } - - public String getDescription() { - return description; - } - - public ManufacturerType getManufacturer() { - return isParentSet() ? parent.manufacturer : manufacturer; - } - - public String getModel() { - return isParentSet() ? parent.model : model; - } - - public PumpCapability getPumpCapability() { - - if (isParentSet()) - return this.pumpCapability == null ? parent.pumpCapability : pumpCapability; - else - return this.pumpCapability; - } - - public double getBolusSize() { - return isParentSet() ? parent.bolusSize : bolusSize; - } - - - public DoseStepSize getSpecialBolusSize() { - return isParentSet() ? parent.specialBolusSize : specialBolusSize; - } - - - public DoseSettings getExtendedBolusSettings() { - return isParentSet() ? parent.extendedBolusSettings : extendedBolusSettings; - } - - - public PumpTempBasalType getPumpTempBasalType() { - return isParentSet() ? parent.pumpTempBasalType : pumpTempBasalType; - } - - - public DoseSettings getTbrSettings() { - return isParentSet() ? parent.tbrSettings : tbrSettings; - } - - - public double getBaseBasalMinValue() { - return isParentSet() ? parent.baseBasalMinValue : baseBasalMinValue; - } - - - public Double getBaseBasalMaxValue() { - return isParentSet() ? parent.baseBasalMaxValue : baseBasalMaxValue; - } - - - public double getBaseBasalStep() { - return isParentSet() ? parent.baseBasalStep : baseBasalStep; - } - - - public DoseStepSize getBaseBasalSpecialSteps() { - return isParentSet() ? parent.baseBasalSpecialSteps : baseBasalSpecialSteps; - } - - - public PumpType getParent() { - return parent; - } - - - private boolean isParentSet() { - return this.parent != null; - } - - - public static PumpType getByDescription(String desc) { - if (mapByDescription.containsKey(desc)) { - return mapByDescription.get(desc); - } else { - return PumpType.GenericAAPS; - } - } - - - public String getFullDescription(String i18nTemplate, boolean hasExtendedBasals, ResourceHelper resourceHelper) { - - String unit = getPumpTempBasalType() == PumpTempBasalType.Percent ? "%" : ""; - - DoseSettings eb = getExtendedBolusSettings(); - DoseSettings tbr = getTbrSettings(); - - String extendedNote = hasExtendedBasals ? resourceHelper.gs(R.string.def_extended_note) : ""; - - return String.format(i18nTemplate, // - getStep("" + getBolusSize(), getSpecialBolusSize()), // - eb.getStep(), eb.getDurationStep(), eb.getMaxDuration() / 60, // - getStep(getBaseBasalRange(), getBaseBasalSpecialSteps()), // - tbr.getMinDose() + unit + "-" + tbr.getMaxDose() + unit, tbr.getStep() + unit, - tbr.getDurationStep(), tbr.getMaxDuration() / 60, extendedNote); - } - - - private String getBaseBasalRange() { - Double maxValue = getBaseBasalMaxValue(); - - return maxValue == null ? "" + getBaseBasalMinValue() : getBaseBasalMinValue() + "-" + maxValue; - } - - - private String getStep(String step, DoseStepSize stepSize) { - if (stepSize != null) - return step + " [" + stepSize.getDescription() + "] *"; - else - return "" + step; - } - - - public boolean hasExtendedBasals() { - return ((getBaseBasalSpecialSteps() != null) || (getSpecialBolusSize() != null)); - } - - - public PumpCapability getSpecialBasalDurations() { - - if (isParentSet()) { - return parent.getSpecialBasalDurations(); - } else { - return specialBasalDurations == null ? // - PumpCapability.BasalRate_Duration15and30minNotAllowed : specialBasalDurations; - } - } - - public double determineCorrectBolusSize(double bolusAmount) { - if (bolusAmount == 0.0d) { - return bolusAmount; - } - - double bolusStepSize = getBolusSize(); - - if (getSpecialBolusSize() != null) { - DoseStepSize specialBolusSize = getSpecialBolusSize(); - bolusStepSize = specialBolusSize.getStepSizeForAmount(bolusAmount); - } - - return Round.roundTo(bolusAmount, bolusStepSize); - } - - - public double determineCorrectBolusStepSize(double bolusAmount) { - DoseStepSize specialBolusSize = getSpecialBolusSize(); - if (specialBolusSize != null) - return specialBolusSize.getStepSizeForAmount(bolusAmount); - return getBolusSize(); - } - - public double determineCorrectExtendedBolusSize(double bolusAmount) { - if (bolusAmount == 0.0d) { - return bolusAmount; - } - - double bolusStepSize; - - if (getExtendedBolusSettings() == null) { // this should be never null - return 0.0d; - } - - DoseSettings extendedBolusSettings = getExtendedBolusSettings(); - - bolusStepSize = extendedBolusSettings.getStep(); - - if (bolusAmount > extendedBolusSettings.getMaxDose()) { - bolusAmount = extendedBolusSettings.getMaxDose(); - } - - return Round.roundTo(bolusAmount, bolusStepSize); - } - - - public double determineCorrectBasalSize(double basalAmount) { - if (basalAmount == 0.0d) { - return basalAmount; - } - - double basalStepSize; - - if (getBaseBasalSpecialSteps() == null) { - basalStepSize = getBaseBasalStep(); - } else { - DoseStepSize specialBolusSize = getBaseBasalSpecialSteps(); - - basalStepSize = specialBolusSize.getStepSizeForAmount(basalAmount); - } - - if (basalAmount > getTbrSettings().getMaxDose()) - basalAmount = getTbrSettings().getMaxDose().doubleValue(); - - return Round.roundTo(basalAmount, basalStepSize); - - } -} diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpType.kt b/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpType.kt new file mode 100644 index 0000000000..23d825f179 --- /dev/null +++ b/core/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpType.kt @@ -0,0 +1,411 @@ +package info.nightscout.androidaps.plugins.pump.common.defs + +import info.nightscout.androidaps.core.R +import info.nightscout.androidaps.plugins.common.ManufacturerType +import info.nightscout.androidaps.plugins.pump.common.data.DoseSettings +import info.nightscout.androidaps.utils.Round +import info.nightscout.androidaps.utils.resources.ResourceHelper +import kotlin.math.min + +@Suppress("unused") +enum class PumpType { + + GENERIC_AAPS(description = "Generic AAPS", + manufacturer = ManufacturerType.AndroidAPS, + model = "VirtualPump", + bolusSize = 0.1, + specialBolusSize = null, + extendedBolusSettings = DoseSettings(0.05, 30, 8 * 60, 0.05), + pumpTempBasalType = PumpTempBasalType.Percent, + tbrSettings = DoseSettings(10.0, 30, 24 * 60, 0.0, 500.0), + specialBasalDurations = PumpCapability.BasalRate_Duration15and30minAllowed, + baseBasalMinValue = 0.01, + baseBasalStep = 0.01, + baseBasalSpecialSteps = null, + pumpCapability = PumpCapability.VirtualPumpCapabilities), + + CELLNOVO(description = "Cellnovo", + manufacturer = ManufacturerType.Cellnovo, + model = "Cellnovo", + bolusSize = 0.05, + specialBolusSize = null, + extendedBolusSettings = DoseSettings(0.05, 30, 24 * 60, 1.0), + pumpTempBasalType = PumpTempBasalType.Percent, + tbrSettings = DoseSettings(5.0, 30, 24 * 60, 0.0, 200.0), + specialBasalDurations = PumpCapability.BasalRate_Duration30minAllowed, + baseBasalMinValue = 0.05, + baseBasalStep = 0.05, + baseBasalSpecialSteps = null, + pumpCapability = PumpCapability.VirtualPumpCapabilities), + + ACCU_CHEK_COMBO(description = "Accu-Chek Combo", + manufacturer = ManufacturerType.Roche, + model = "Combo", + bolusSize = 0.1, + specialBolusSize = null, + extendedBolusSettings = DoseSettings(0.1, 15, 12 * 60, 0.1), + pumpTempBasalType = PumpTempBasalType.Percent, + tbrSettings = DoseSettings(10.0, 15, 12 * 60, 0.0, 500.0), + specialBasalDurations = PumpCapability.BasalRate_Duration15and30minAllowed, + baseBasalMinValue = 0.01, + baseBasalStep = 0.01, + baseBasalSpecialSteps = DoseStepSize.ComboBasal, + pumpCapability = PumpCapability.ComboCapabilities), + ACCU_CHEK_SPIRIT(description = "Accu-Chek Spirit", + manufacturer = ManufacturerType.Roche, + model = "Spirit", + bolusSize = 0.1, + specialBolusSize = null, + extendedBolusSettings = DoseSettings(0.1, 15, 12 * 60, 0.1), + pumpTempBasalType = PumpTempBasalType.Percent, + tbrSettings = DoseSettings(10.0, 15, 12 * 60, 0.0, 500.0), + specialBasalDurations = PumpCapability.BasalRate_Duration15and30minAllowed, + baseBasalMinValue = 0.01, + baseBasalStep = 0.1, + baseBasalSpecialSteps = null, + pumpCapability = PumpCapability.VirtualPumpCapabilities), + ACCU_CHEK_INSIGHT(description = "Accu-Chek Insight", + manufacturer = ManufacturerType.Roche, + model = "Insight", + bolusSize = 0.05, + specialBolusSize = DoseStepSize.InsightBolus, + extendedBolusSettings = DoseSettings(0.05, 15, 24 * 60, 0.05), + pumpTempBasalType = PumpTempBasalType.Percent, + tbrSettings = DoseSettings(10.0, 15, 24 * 60, 0.0, 250.0), + specialBasalDurations = PumpCapability.BasalRate_Duration15and30minAllowed, + baseBasalMinValue = 0.02, + baseBasalStep = 0.01, + baseBasalSpecialSteps = null, + pumpCapability = PumpCapability.InsightCapabilities), + ACCU_CHEK_INSIGHT_BLUETOOTH(description = "Accu-Chek Insight", + manufacturer = ManufacturerType.Roche, + model = "Insight", + bolusSize = 0.01, + specialBolusSize = null, + extendedBolusSettings = DoseSettings(0.01, 15, 24 * 60, 0.05), + pumpTempBasalType = PumpTempBasalType.Percent, + tbrSettings = DoseSettings(10.0, 15, 24 * 60, 0.0, 250.0), + specialBasalDurations = PumpCapability.BasalRate_Duration15and30minAllowed, + baseBasalMinValue = 0.02, + baseBasalMaxValue = null, + baseBasalStep = 0.01, + baseBasalSpecialSteps = DoseStepSize.InsightBolus, + pumpCapability = PumpCapability.InsightCapabilities), + ACCU_CHEK_SOLO(description = "Accu-Chek Solo", + manufacturer = ManufacturerType.Roche, + model = "Solo", + bolusSize = 0.01, + specialBolusSize = null, + extendedBolusSettings = DoseSettings(0.01, 15, 24 * 60, 0.05), + pumpTempBasalType = PumpTempBasalType.Percent, + tbrSettings = DoseSettings(10.0, 15, 24 * 60, 0.0, 250.0), + specialBasalDurations = PumpCapability.BasalRate_Duration15and30minAllowed, + baseBasalMinValue = 0.02, + baseBasalMaxValue = null, + baseBasalStep = 0.01, + baseBasalSpecialSteps = DoseStepSize.InsightBolus, + pumpCapability = PumpCapability.InsightCapabilities), + + ANIMAS_VIBE(description = "Animas Vibe", + manufacturer = ManufacturerType.Animas, + model = "Vibe", + bolusSize = 0.05, + specialBolusSize = null, + extendedBolusSettings = DoseSettings(0.05, 30, 12 * 60, 0.05), + pumpTempBasalType = PumpTempBasalType.Percent, + tbrSettings = DoseSettings(10.0, 30, 24 * 60, 0.0, 300.0), + specialBasalDurations = PumpCapability.BasalRate_Duration30minAllowed, + baseBasalMinValue = 0.025, + baseBasalMaxValue = 5.0, + baseBasalStep = 0.0, + baseBasalSpecialSteps = null, + pumpCapability = PumpCapability.VirtualPumpCapabilities), + ANIMAS_PING(description = "Animas Ping", model = "Ping", parent = ANIMAS_VIBE), + DANA_R(description = "DanaR", + manufacturer = ManufacturerType.Sooil, + model = "DanaR", + bolusSize = 0.05, + specialBolusSize = null, + extendedBolusSettings = DoseSettings(0.05, 30, 8 * 60, 0.05), + pumpTempBasalType = PumpTempBasalType.Percent, + tbrSettings = DoseSettings(10.0, 60, 24 * 60, 0.0, 200.0), + specialBasalDurations = PumpCapability.BasalRate_Duration15and30minNotAllowed, + baseBasalMinValue = 0.04, + baseBasalStep = 0.01, + baseBasalSpecialSteps = null, + pumpCapability = PumpCapability.DanaCapabilities), + DANA_R_KOREAN(description = "DanaR Korean", + manufacturer = ManufacturerType.Sooil, + model = "DanaRKorean", + bolusSize = 0.05, + specialBolusSize = null, + extendedBolusSettings = DoseSettings(0.05, 30, 8 * 60, 0.05), + pumpTempBasalType = PumpTempBasalType.Percent, + tbrSettings = DoseSettings(10.0, 60, 24 * 60, 0.0, 200.0), + specialBasalDurations = PumpCapability.BasalRate_Duration15and30minNotAllowed, + baseBasalMinValue = 0.1, + baseBasalStep = 0.01, + baseBasalSpecialSteps = null, + pumpCapability = PumpCapability.DanaCapabilities), + DANA_RS(description = "DanaRS", + manufacturer = ManufacturerType.Sooil, + model = "DanaRS", + bolusSize = 0.05, + specialBolusSize = null, + extendedBolusSettings = DoseSettings(0.05, 30, 8 * 60, 0.05), + pumpTempBasalType = PumpTempBasalType.Percent, + tbrSettings = DoseSettings(10.0, 60, 24 * 60, 0.0, 200.0), + specialBasalDurations = PumpCapability.BasalRate_Duration15and30minAllowed, + baseBasalMinValue = 0.04, + baseBasalStep = 0.01, + baseBasalSpecialSteps = null, + pumpCapability = PumpCapability.DanaWithHistoryCapabilities), + DANA_RV2(description = "DanaRv2", model = "DanaRv2", parent = DANA_RS), + OMNIPOD_EROS(description = "Omnipod Eros", + manufacturer = ManufacturerType.Insulet, + model = "Eros", + bolusSize = 0.05, + specialBolusSize = null, + extendedBolusSettings = DoseSettings(0.05, 30, 8 * 60, 0.05), + pumpTempBasalType = PumpTempBasalType.Absolute, + tbrSettings = DoseSettings(0.05, 30, 12 * 60, 0.0, 30.0), + specialBasalDurations = PumpCapability.BasalRate_Duration30minAllowed, + baseBasalMinValue = 0.05, + baseBasalMaxValue = null, + baseBasalStep = 0.05, + baseBasalSpecialSteps = null, + pumpCapability = PumpCapability.OmnipodCapabilities, + hasCustomUnreachableAlertCheck = true), + OMNIPOD_DASH(description = "Omnipod Dash", + manufacturer = ManufacturerType.Insulet, + model = "Dash", + bolusSize = 0.05, + specialBolusSize = null, + extendedBolusSettings = DoseSettings(0.05, 30, 8 * 60, 0.05), + pumpTempBasalType = PumpTempBasalType.Absolute, + tbrSettings = DoseSettings(0.05, 30, 12 * 60, 0.0, 30.0), + specialBasalDurations = PumpCapability.BasalRate_Duration30minAllowed, + baseBasalMinValue = 0.05, + baseBasalMaxValue = null, + baseBasalStep = 0.05, + baseBasalSpecialSteps = null, + pumpCapability = PumpCapability.OmnipodCapabilities, + hasCustomUnreachableAlertCheck = false), + MEDTRONIC_512_712(description = "Medtronic 512/712", + manufacturer = ManufacturerType.Medtronic, + model = "512/712", + bolusSize = 0.1, + specialBolusSize = null, + extendedBolusSettings = DoseSettings(0.05, 30, 8 * 60, 0.05), + pumpTempBasalType = PumpTempBasalType.Absolute, + tbrSettings = DoseSettings(0.05, 30, 24 * 60, 0.0, 35.0), + specialBasalDurations = PumpCapability.BasalRate_Duration30minAllowed, + baseBasalMinValue = 0.05, + baseBasalStep = 0.05, + baseBasalSpecialSteps = null, + pumpCapability = PumpCapability.MedtronicCapabilities), + MEDTRONIC_515_715(description = "Medtronic 515/715", + model = "515/715", + parent = MEDTRONIC_512_712), + MEDTRONIC_522_722(description = "Medtronic 522/722", + model = "522/722", + parent = MEDTRONIC_512_712), + MEDTRONIC_523_723_REVEL(description = "Medtronic 523/723 (Revel)", + manufacturer = ManufacturerType.Medtronic, + model = "523/723 (Revel)", + bolusSize = 0.05, + specialBolusSize = null, + extendedBolusSettings = DoseSettings(0.05, 30, 8 * 60, 0.05), + pumpTempBasalType = PumpTempBasalType.Absolute, + tbrSettings = DoseSettings(0.05, 30, 24 * 60, 0.0, 35.0), + specialBasalDurations = PumpCapability.BasalRate_Duration30minAllowed, + baseBasalMinValue = 0.025, + baseBasalStep = 0.025, + baseBasalSpecialSteps = DoseStepSize.MedtronicVeoBasal, + pumpCapability = PumpCapability.MedtronicCapabilities), + MEDTRONIC_554_754_VEO(description = "Medtronic 554/754 (Veo)", model = "554/754 (Veo)", parent = MEDTRONIC_523_723_REVEL), + MEDTRONIC_640G(description = "Medtronic 640G", + manufacturer = ManufacturerType.Medtronic, + model = "640G", + bolusSize = 0.025, + specialBolusSize = null, + extendedBolusSettings = DoseSettings(0.05, 30, 8 * 60, 0.05), + pumpTempBasalType = PumpTempBasalType.Absolute, + tbrSettings = DoseSettings(0.05, 30, 24 * 60, 0.0, 35.0), + specialBasalDurations = PumpCapability.BasalRate_Duration30minAllowed, + baseBasalMinValue = 0.025, + baseBasalStep = 0.025, + baseBasalSpecialSteps = DoseStepSize.MedtronicVeoBasal, + pumpCapability = PumpCapability.VirtualPumpCapabilities), + + TANDEM_T_SLIM(description = "Tandem t:slim", + manufacturer = ManufacturerType.Tandem, + model = "t:slim", + bolusSize = 0.01, + specialBolusSize = null, + extendedBolusSettings = DoseSettings(0.01, 15, 8 * 60, 0.4), + pumpTempBasalType = PumpTempBasalType.Percent, + tbrSettings = DoseSettings(1.0, 15, 8 * 60, 0.0, 250.0), + specialBasalDurations = PumpCapability.BasalRate_Duration15and30minAllowed, + baseBasalMinValue = 0.1, + baseBasalStep = 0.001, + baseBasalSpecialSteps = null, + pumpCapability = PumpCapability.VirtualPumpCapabilities), + TANDEM_T_FLEX(description = "Tandem t:flex", model = "t:flex", parent = TANDEM_T_SLIM), + TANDEM_T_SLIM_G4(description = "Tandem t:slim G4", model = "t:slim G4", parent = TANDEM_T_SLIM), + TANDEM_T_SLIM_X2(description = "Tandem t:slim X2", model = "t:slim X2", parent = TANDEM_T_SLIM), + + YPSOPUMP(description = "YpsoPump", + manufacturer = ManufacturerType.Ypsomed, + model = "Ypsopump", + bolusSize = 0.1, + specialBolusSize = null, + extendedBolusSettings = DoseSettings(0.1, 15, 12 * 60, 0.1), + pumpTempBasalType = PumpTempBasalType.Percent, + tbrSettings = DoseSettings(1.0, 15, 24 * 60, 0.0, 500.0), + specialBasalDurations = PumpCapability.BasalRate_Duration15and30minAllowed, + baseBasalMinValue = 0.02, + baseBasalMaxValue = 40.0, + baseBasalStep = 0.01, + baseBasalSpecialSteps = DoseStepSize.YpsopumpBasal, + pumpCapability = PumpCapability.YpsomedCapabilities), + MDI(description = "MDI", + manufacturer = ManufacturerType.AndroidAPS, + model = "MDI", + tbrSettings = DoseSettings(1.0, 15, 24 * 60, 0.0, 500.0), + extendedBolusSettings = DoseSettings(0.1, 15, 12 * 60, 0.1), + pumpCapability = PumpCapability.MDI), + // Not real pump. Used for User as a source + USER(description = "USER", + manufacturer = ManufacturerType.AndroidAPS, + model = "USER", + tbrSettings = DoseSettings(1.0, 15, 24 * 60, 0.0, 500.0), + extendedBolusSettings = DoseSettings(0.1, 15, 12 * 60, 0.1), + pumpCapability = PumpCapability.MDI); + + val description: String + var manufacturer: ManufacturerType? = null + get() = parent?.manufacturer ?: field + private set + var model: String = "NONE" + get() = parent?.model ?: field + private set + var bolusSize = 0.0 + get() = parent?.bolusSize ?: field + private var specialBolusSize: DoseStepSize? = null + get() = parent?.specialBolusSize ?: field + var extendedBolusSettings: DoseSettings? = null + get() = parent?.extendedBolusSettings ?: field + private set + var pumpTempBasalType: PumpTempBasalType? = null + get() = parent?.pumpTempBasalType ?: field + private set + var tbrSettings: DoseSettings? = null + get() = parent?.tbrSettings ?: field + private set + var specialBasalDurations: PumpCapability? = null + get() = parent?.specialBasalDurations ?: field + ?: PumpCapability.BasalRate_Duration15and30minNotAllowed + private set + var baseBasalMinValue = 0.01 + get() = parent?.baseBasalMinValue ?: field + private set + private var baseBasalMaxValue: Double? = null + get() = parent?.baseBasalMaxValue ?: field + var baseBasalStep = 1.0 + get() = parent?.baseBasalStep ?: field + private set + private var baseBasalSpecialSteps: DoseStepSize? = null + get() = parent?.baseBasalSpecialSteps ?: field + var pumpCapability: PumpCapability? = null + get() = parent?.pumpCapability ?: field + private set + var hasCustomUnreachableAlertCheck = false + private set + private var parent: PumpType? = null + + companion object { + + fun getByDescription(desc: String): PumpType = + values().firstOrNull { it.description == desc } ?: GENERIC_AAPS + } + + constructor(description: String, model: String, parent: PumpType, pumpCapability: PumpCapability? = null) { + this.description = description + this.parent = parent + this.pumpCapability = pumpCapability + parent.model = model + } + + constructor(description: String, + manufacturer: ManufacturerType, + model: String, + bolusSize: Double = 0.0, + specialBolusSize: DoseStepSize? = null, + extendedBolusSettings: DoseSettings, + pumpTempBasalType: PumpTempBasalType? = null, + tbrSettings: DoseSettings, + specialBasalDurations: PumpCapability? = null, + baseBasalMinValue: Double = 0.01, + baseBasalMaxValue: Double? = null, + baseBasalStep: Double = 1.0, + baseBasalSpecialSteps: DoseStepSize? = null, + pumpCapability: PumpCapability, + hasCustomUnreachableAlertCheck: Boolean = false) { + this.description = description + this.manufacturer = manufacturer + this.model = model + this.bolusSize = bolusSize + this.specialBolusSize = specialBolusSize + this.extendedBolusSettings = extendedBolusSettings + this.pumpTempBasalType = pumpTempBasalType + this.tbrSettings = tbrSettings + this.specialBasalDurations = specialBasalDurations + this.baseBasalMinValue = baseBasalMinValue + this.baseBasalMaxValue = baseBasalMaxValue + this.baseBasalStep = baseBasalStep + this.baseBasalSpecialSteps = baseBasalSpecialSteps + this.pumpCapability = pumpCapability + this.hasCustomUnreachableAlertCheck = hasCustomUnreachableAlertCheck + } + + fun getFullDescription(i18nTemplate: String, hasExtendedBasals: Boolean, resourceHelper: ResourceHelper): String { + val unit = if (pumpTempBasalType == PumpTempBasalType.Percent) "%" else "" + val eb = extendedBolusSettings ?: return "INVALID" + val tbr = tbrSettings ?: return "INVALID" + val extendedNote = if (hasExtendedBasals) resourceHelper.gs(R.string.def_extended_note) else "" + return String.format(i18nTemplate, + getStep("" + bolusSize, specialBolusSize), + eb.step, eb.durationStep, eb.maxDuration / 60, + getStep(baseBasalRange(), baseBasalSpecialSteps), + tbr.minDose.toString() + unit + "-" + tbr.maxDose + unit, tbr.step.toString() + unit, + tbr.durationStep, tbr.maxDuration / 60, extendedNote) + } + + private fun baseBasalRange(): String = + if (baseBasalMaxValue == null) baseBasalMinValue.toString() + else baseBasalMinValue.toString() + "-" + baseBasalMaxValue.toString() + + private fun getStep(step: String, stepSize: DoseStepSize?): String = + if (stepSize != null) step + " [" + stepSize.description + "] *" + else step + + fun hasExtendedBasals(): Boolean = baseBasalSpecialSteps != null || specialBolusSize != null + + fun determineCorrectBolusSize(bolusAmount: Double): Double = + Round.roundTo(bolusAmount, specialBolusSize?.getStepSizeForAmount(bolusAmount) ?: bolusSize) + + fun determineCorrectBolusStepSize(bolusAmount: Double): Double = + specialBolusSize?.getStepSizeForAmount(bolusAmount) ?: bolusSize + + fun determineCorrectExtendedBolusSize(bolusAmount: Double): Double { + val ebSettings = extendedBolusSettings ?: throw IllegalStateException() + return Round.roundTo(min(bolusAmount, ebSettings.maxDose), ebSettings.step) + } + + fun determineCorrectBasalSize(basalAmount: Double): Double { + val tSettings = tbrSettings ?: throw IllegalStateException() + return Round.roundTo(min(basalAmount, tSettings.maxDose), baseBasalSpecialSteps?.getStepSizeForAmount(basalAmount) + ?: baseBasalStep) + } +} \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/utils/extensions/BolusExtension.kt b/core/src/main/java/info/nightscout/androidaps/utils/extensions/BolusExtension.kt new file mode 100644 index 0000000000..f8814e0384 --- /dev/null +++ b/core/src/main/java/info/nightscout/androidaps/utils/extensions/BolusExtension.kt @@ -0,0 +1,12 @@ +package info.nightscout.androidaps.utils.extensions + +import info.nightscout.androidaps.data.Iob +import info.nightscout.androidaps.database.entities.Bolus +import info.nightscout.androidaps.interfaces.ActivePluginProvider +import info.nightscout.androidaps.interfaces.InsulinInterface + +fun Bolus.iobCalc(activePlugin: ActivePluginProvider, time: Long, dia: Double): Iob { + if (!isValid) return Iob() + val insulinInterface: InsulinInterface = activePlugin.activeInsulin + return insulinInterface.iobCalcForTreatment(this, time, dia) +} diff --git a/core/src/main/java/info/nightscout/androidaps/utils/extensions/CarbsExtension.kt b/core/src/main/java/info/nightscout/androidaps/utils/extensions/CarbsExtension.kt new file mode 100644 index 0000000000..bf2f6e6cb3 --- /dev/null +++ b/core/src/main/java/info/nightscout/androidaps/utils/extensions/CarbsExtension.kt @@ -0,0 +1,26 @@ +package info.nightscout.androidaps.utils.extensions + +import info.nightscout.androidaps.database.entities.Carbs +import info.nightscout.androidaps.utils.T +import kotlin.math.roundToInt + +fun Carbs.expandCarbs(): List = + mutableListOf().also { carbs -> + if (this.duration == 0L) { + carbs.add(this) + } else { + var remainingCarbs = this.amount + val ticks = T.msecs(this.duration).mins() * 4 //duration guaranteed to be integer greater zero + for (i in 0 until ticks) { + val carbTime = this.timestamp + i * 15 * 60 * 1000 + val smallCarbAmount = (1.0 * remainingCarbs / (ticks - i)).roundToInt() //on last iteration (ticks-i) is 1 -> smallCarbAmount == remainingCarbs + remainingCarbs -= smallCarbAmount.toLong() + if (smallCarbAmount > 0) + carbs.add(Carbs( + timestamp = carbTime, + amount = smallCarbAmount.toDouble(), + duration = 0 + )) + } + } + } diff --git a/core/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt b/core/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt index 97727ab5af..d104302084 100644 --- a/core/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt +++ b/core/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt @@ -57,7 +57,7 @@ class TestPumpPlugin(val injector: HasAndroidInjector) : PumpInterface { override fun cancelExtendedBolus(): PumpEnactResult = PumpEnactResult(injector).success(true) override fun getJSONStatus(profile: Profile, profileName: String, version: String): JSONObject = JSONObject() override fun manufacturer(): ManufacturerType = ManufacturerType.AndroidAPS - override fun model(): PumpType = PumpType.GenericAAPS + override fun model(): PumpType = PumpType.GENERIC_AAPS override fun serialNumber(): String = "1" override fun shortStatus(veryShort: Boolean): String = "" override val isFakingTempsByExtendedBoluses: Boolean = false diff --git a/core/src/test/java/info/nightscout/androidaps/data/DetailedBolusInfoTest.kt b/core/src/test/java/info/nightscout/androidaps/data/DetailedBolusInfoTest.kt index 2c6ec487b1..64142eea19 100644 --- a/core/src/test/java/info/nightscout/androidaps/data/DetailedBolusInfoTest.kt +++ b/core/src/test/java/info/nightscout/androidaps/data/DetailedBolusInfoTest.kt @@ -49,12 +49,12 @@ class DetailedBolusInfoTest : TestBase() { detailedBolusInfo.glucoseType = TherapyEvent.MeterType.FINGER val therapyEvent = detailedBolusInfo.createTherapyEvent() - Assert.assertEquals(1000L, therapyEvent?.timestamp) - Assert.assertEquals(TherapyEvent.Type.NOTE, therapyEvent?.type) - Assert.assertEquals(TherapyEvent.GlucoseUnit.MGDL, therapyEvent?.glucoseUnit) - Assert.assertEquals("note", therapyEvent?.note) - Assert.assertEquals(180.0, therapyEvent?.glucose) - Assert.assertEquals(TherapyEvent.MeterType.FINGER, therapyEvent?.glucoseType) + Assert.assertEquals(1000L, therapyEvent.timestamp) + Assert.assertEquals(TherapyEvent.Type.NOTE, therapyEvent.type) + Assert.assertEquals(TherapyEvent.GlucoseUnit.MGDL, therapyEvent.glucoseUnit) + Assert.assertEquals("note", therapyEvent.note) + Assert.assertEquals(180.0, therapyEvent.glucose) + Assert.assertEquals(TherapyEvent.MeterType.FINGER, therapyEvent.glucoseType) } @Test @@ -110,7 +110,7 @@ class DetailedBolusInfoTest : TestBase() { superbolusInsulin = 1.0, wasTempTargetUsed = true, totalInsulin = 15.0, - percentageCorrection = 50.0, + percentageCorrection = 50, profileName = "profile" ) } \ No newline at end of file diff --git a/core/src/test/java/info/nightscout/androidaps/interfaces/PumpDescriptionTest.kt b/core/src/test/java/info/nightscout/androidaps/interfaces/PumpDescriptionTest.kt index 96f7edd776..392c7f9791 100644 --- a/core/src/test/java/info/nightscout/androidaps/interfaces/PumpDescriptionTest.kt +++ b/core/src/test/java/info/nightscout/androidaps/interfaces/PumpDescriptionTest.kt @@ -6,30 +6,27 @@ import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import org.junit.Assert import org.junit.Test -/** - * Created by andy on 5/13/18. - */ class PumpDescriptionTest { @Test fun setPumpDescription() { val pumpDescription = PumpDescription() - pumpDescription.setPumpDescription(PumpType.AccuChekCombo) - Assert.assertEquals(pumpDescription.bolusStep, PumpType.AccuChekCombo.bolusSize, 0.1) - Assert.assertEquals(pumpDescription.basalMinimumRate, PumpType.AccuChekCombo.baseBasalStep, 0.1) - Assert.assertEquals(pumpDescription.basalStep, PumpType.AccuChekCombo.baseBasalStep, 0.1) - Assert.assertEquals(pumpDescription.extendedBolusDurationStep, PumpType.AccuChekCombo.extendedBolusSettings.durationStep.toDouble(), 0.1) - Assert.assertEquals(pumpDescription.extendedBolusMaxDuration, PumpType.AccuChekCombo.extendedBolusSettings.maxDuration.toDouble(), 0.1) - Assert.assertEquals(pumpDescription.extendedBolusStep, PumpType.AccuChekCombo.extendedBolusSettings.step, 0.1) - Assert.assertEquals(pumpDescription.isExtendedBolusCapable, PumpType.AccuChekCombo.pumpCapability.hasCapability(PumpCapability.ExtendedBolus)) - Assert.assertEquals(pumpDescription.isBolusCapable, PumpType.AccuChekCombo.pumpCapability.hasCapability(PumpCapability.Bolus)) - Assert.assertEquals(pumpDescription.isRefillingCapable, PumpType.AccuChekCombo.pumpCapability.hasCapability(PumpCapability.Refill)) - Assert.assertEquals(pumpDescription.isSetBasalProfileCapable, PumpType.AccuChekCombo.pumpCapability.hasCapability(PumpCapability.BasalProfileSet)) - Assert.assertEquals(pumpDescription.isTempBasalCapable, PumpType.AccuChekCombo.pumpCapability.hasCapability(PumpCapability.TempBasal)) - Assert.assertEquals(pumpDescription.maxTempPercent.toDouble(), PumpType.AccuChekCombo.tbrSettings.maxDose, 0.1) - Assert.assertEquals(pumpDescription.tempPercentStep.toDouble(), PumpType.AccuChekCombo.tbrSettings.step, 0.1) - Assert.assertEquals(pumpDescription.tempBasalStyle, if (PumpType.AccuChekCombo.pumpTempBasalType == PumpTempBasalType.Percent) PumpDescription.PERCENT else PumpDescription.ABSOLUTE) - Assert.assertEquals(pumpDescription.tempDurationStep.toLong(), PumpType.AccuChekCombo.tbrSettings.durationStep.toLong()) - Assert.assertEquals(pumpDescription.tempDurationStep15mAllowed, PumpType.AccuChekCombo.specialBasalDurations.hasCapability(PumpCapability.BasalRate_Duration15minAllowed)) - Assert.assertEquals(pumpDescription.tempDurationStep30mAllowed, PumpType.AccuChekCombo.specialBasalDurations.hasCapability(PumpCapability.BasalRate_Duration30minAllowed)) + pumpDescription.setPumpDescription(PumpType.ACCU_CHEK_COMBO) + Assert.assertEquals(pumpDescription.bolusStep, PumpType.ACCU_CHEK_COMBO.bolusSize, 0.1) + Assert.assertEquals(pumpDescription.basalMinimumRate, PumpType.ACCU_CHEK_COMBO.baseBasalStep, 0.1) + Assert.assertEquals(pumpDescription.basalStep, PumpType.ACCU_CHEK_COMBO.baseBasalStep, 0.1) + Assert.assertEquals(pumpDescription.extendedBolusDurationStep, PumpType.ACCU_CHEK_COMBO.extendedBolusSettings?.durationStep?.toDouble()) + Assert.assertEquals(pumpDescription.extendedBolusMaxDuration, PumpType.ACCU_CHEK_COMBO.extendedBolusSettings?.maxDuration?.toDouble()) + Assert.assertEquals(pumpDescription.extendedBolusStep, PumpType.ACCU_CHEK_COMBO.extendedBolusSettings?.step) + Assert.assertEquals(pumpDescription.isExtendedBolusCapable, PumpType.ACCU_CHEK_COMBO.pumpCapability?.hasCapability(PumpCapability.ExtendedBolus)) + Assert.assertEquals(pumpDescription.isBolusCapable, PumpType.ACCU_CHEK_COMBO.pumpCapability?.hasCapability(PumpCapability.Bolus)) + Assert.assertEquals(pumpDescription.isRefillingCapable, PumpType.ACCU_CHEK_COMBO.pumpCapability?.hasCapability(PumpCapability.Refill)) + Assert.assertEquals(pumpDescription.isSetBasalProfileCapable, PumpType.ACCU_CHEK_COMBO.pumpCapability?.hasCapability(PumpCapability.BasalProfileSet)) + Assert.assertEquals(pumpDescription.isTempBasalCapable, PumpType.ACCU_CHEK_COMBO.pumpCapability?.hasCapability(PumpCapability.TempBasal)) + Assert.assertEquals(pumpDescription.maxTempPercent.toDouble(), PumpType.ACCU_CHEK_COMBO.tbrSettings?.maxDose) + Assert.assertEquals(pumpDescription.tempPercentStep.toDouble(), PumpType.ACCU_CHEK_COMBO.tbrSettings?.step) + Assert.assertEquals(pumpDescription.tempBasalStyle, if (PumpType.ACCU_CHEK_COMBO.pumpTempBasalType == PumpTempBasalType.Percent) PumpDescription.PERCENT else PumpDescription.ABSOLUTE) + Assert.assertEquals(pumpDescription.tempDurationStep.toLong(), PumpType.ACCU_CHEK_COMBO.tbrSettings?.durationStep?.toLong()) + Assert.assertEquals(pumpDescription.tempDurationStep15mAllowed, PumpType.ACCU_CHEK_COMBO.specialBasalDurations?.hasCapability(PumpCapability.BasalRate_Duration15minAllowed)) + Assert.assertEquals(pumpDescription.tempDurationStep30mAllowed, PumpType.ACCU_CHEK_COMBO.specialBasalDurations?.hasCapability(PumpCapability.BasalRate_Duration30minAllowed)) } } \ No newline at end of file diff --git a/core/src/test/java/info/nightscout/androidaps/plugins/aps/loop/APSResultTest.kt b/core/src/test/java/info/nightscout/androidaps/plugins/aps/loop/APSResultTest.kt index d591fd3e87..159659f4de 100644 --- a/core/src/test/java/info/nightscout/androidaps/plugins/aps/loop/APSResultTest.kt +++ b/core/src/test/java/info/nightscout/androidaps/plugins/aps/loop/APSResultTest.kt @@ -49,7 +49,7 @@ class APSResultTest : TestBaseWithProfile() { // BASAL RATE IN TEST PROFILE IS 1U/h // **** PERCENT pump **** - testPumpPlugin.pumpDescription.setPumpDescription(PumpType.Cellnovo1) // % based + testPumpPlugin.pumpDescription.setPumpDescription(PumpType.CELLNOVO) // % based apsResult.usePercent(true) // closed loop mode return original request @@ -107,7 +107,7 @@ class APSResultTest : TestBaseWithProfile() { Assert.assertEquals(true, apsResult.isChangeRequested) // **** ABSOLUTE pump **** - testPumpPlugin.pumpDescription.setPumpDescription(PumpType.Medtronic_515_715) // U/h based + testPumpPlugin.pumpDescription.setPumpDescription(PumpType.MEDTRONIC_515_715) // U/h based apsResult.usePercent(false) // open loop diff --git a/dana/src/main/java/info/nightscout/androidaps/dana/DanaFragment.kt b/dana/src/main/java/info/nightscout/androidaps/dana/DanaFragment.kt index b0100f93c3..b6ffdf0980 100644 --- a/dana/src/main/java/info/nightscout/androidaps/dana/DanaFragment.kt +++ b/dana/src/main/java/info/nightscout/androidaps/dana/DanaFragment.kt @@ -10,7 +10,7 @@ import android.view.ViewGroup import dagger.android.support.DaggerFragment import info.nightscout.androidaps.activities.TDDStatsActivity import info.nightscout.androidaps.dana.databinding.DanarFragmentBinding -import info.nightscout.androidaps.database.entities.UserEntry.* +import info.nightscout.androidaps.database.entities.UserEntry import info.nightscout.androidaps.dialogs.ProfileViewerDialog import info.nightscout.androidaps.events.EventExtendedBolusChange import info.nightscout.androidaps.events.EventInitializationChanged @@ -105,11 +105,11 @@ class DanaFragment : DaggerFragment() { danaPump.lastConnection = 0 commandQueue.readStatus("Clicked connect to pump", null) } - if (activePlugin.activePump.pumpDescription.pumpType == PumpType.DanaRS) + if (activePlugin.activePump.pumpDescription.pumpType == PumpType.DANA_RS) binding.btconnection.setOnLongClickListener { activity?.let { OKDialog.showConfirmation(it, resourceHelper.gs(R.string.resetpairing)) { - uel.log(Action.CLEAR_PAIRING_KEYS) + uel.log(UserEntry.Action.CLEAR_PAIRING_KEYS) (activePlugin.activePump as DanaPumpInterface).clearPairing() } } diff --git a/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaHistoryActivity.kt b/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaHistoryActivity.kt index 29bb7789ca..2ce2c0164b 100644 --- a/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaHistoryActivity.kt +++ b/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaHistoryActivity.kt @@ -91,8 +91,8 @@ class DanaHistoryActivity : NoSplashAppCompatActivity() { binding.status.visibility = View.GONE val pump = activePlugin.activePump - val isKorean = pump.pumpDescription.pumpType == PumpType.DanaRKorean - val isRS = pump.pumpDescription.pumpType == PumpType.DanaRS + val isKorean = pump.pumpDescription.pumpType == PumpType.DANA_R_KOREAN + val isRS = pump.pumpDescription.pumpType == PumpType.DANA_RS // Types val typeList = ArrayList() diff --git a/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaUserOptionsActivity.kt b/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaUserOptionsActivity.kt index e6e8698e13..c96237455c 100644 --- a/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaUserOptionsActivity.kt +++ b/dana/src/main/java/info/nightscout/androidaps/dana/activities/DanaUserOptionsActivity.kt @@ -39,9 +39,9 @@ class DanaUserOptionsActivity : NoSplashAppCompatActivity() { private val disposable = CompositeDisposable() // This is for Dana pumps only - private fun isRS() = activePlugin.activePump.pumpDescription.pumpType == PumpType.DanaRS - private fun isDanaR() = activePlugin.activePump.pumpDescription.pumpType == PumpType.DanaR - private fun isDanaRv2() = activePlugin.activePump.pumpDescription.pumpType == PumpType.DanaRv2 + private fun isRS() = activePlugin.activePump.pumpDescription.pumpType == PumpType.DANA_RS + private fun isDanaR() = activePlugin.activePump.pumpDescription.pumpType == PumpType.DANA_R + private fun isDanaRv2() = activePlugin.activePump.pumpDescription.pumpType == PumpType.DANA_RV2 var minBacklight = 1 diff --git a/danar/src/main/java/info/nightscout/androidaps/danaRKorean/DanaRKoreanPlugin.java b/danar/src/main/java/info/nightscout/androidaps/danaRKorean/DanaRKoreanPlugin.java index 16c9c49bd6..5aa0fcafe0 100644 --- a/danar/src/main/java/info/nightscout/androidaps/danaRKorean/DanaRKoreanPlugin.java +++ b/danar/src/main/java/info/nightscout/androidaps/danaRKorean/DanaRKoreanPlugin.java @@ -19,7 +19,6 @@ import info.nightscout.androidaps.danar.R; import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.PumpEnactResult; -import info.nightscout.androidaps.database.entities.Bolus; import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.db.Treatment; @@ -77,7 +76,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin { getPluginDescription().description(R.string.description_pump_dana_r_korean); useExtendedBoluses = sp.getBoolean(R.string.key_danar_useextended, false); - pumpDescription.setPumpDescription(PumpType.DanaRKorean); + pumpDescription.setPumpDescription(PumpType.DANA_R_KOREAN); } @Override @@ -165,7 +164,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin { detailedBolusInfo.insulin = constraintChecker.applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value(); if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) { Treatment t = new Treatment(); - t.isSMB = detailedBolusInfo.getBolusType() == Bolus.Type.SMB; + t.isSMB = detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB; boolean connectionOK = false; if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) detailedBolusInfo.carbs, detailedBolusInfo.carbTime, t); @@ -326,7 +325,7 @@ public class DanaRKoreanPlugin extends AbstractDanaRPlugin { @NonNull @Override public PumpType model() { - return PumpType.DanaRKorean; + return PumpType.DANA_R_KOREAN; } private PumpEnactResult cancelRealTempBasal() { diff --git a/danar/src/main/java/info/nightscout/androidaps/danaRv2/DanaRv2Plugin.java b/danar/src/main/java/info/nightscout/androidaps/danaRv2/DanaRv2Plugin.java index 38585f796e..f13c4ebbd8 100644 --- a/danar/src/main/java/info/nightscout/androidaps/danaRv2/DanaRv2Plugin.java +++ b/danar/src/main/java/info/nightscout/androidaps/danaRv2/DanaRv2Plugin.java @@ -19,7 +19,6 @@ import info.nightscout.androidaps.danar.R; import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.PumpEnactResult; -import info.nightscout.androidaps.database.entities.Bolus; import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.db.Treatment; import info.nightscout.androidaps.events.EventAppExit; @@ -82,7 +81,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { getPluginDescription().description(R.string.description_pump_dana_r_v2); useExtendedBoluses = false; - pumpDescription.setPumpDescription(PumpType.DanaRv2); + pumpDescription.setPumpDescription(PumpType.DANA_RV2); } @Override @@ -184,7 +183,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { detailedBolusInfoStorage.add(detailedBolusInfo); // will be picked up on reading history Treatment t = new Treatment(); - t.isSMB = detailedBolusInfo.getBolusType() == Bolus.Type.SMB; + t.isSMB = detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB; boolean connectionOK = false; if (detailedBolusInfo.insulin > 0 || carbs > 0) connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) carbs, DateUtil.now() + T.mins(carbTime).msecs(), t); @@ -350,7 +349,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { @NonNull @Override public PumpType model() { - return PumpType.DanaRv2; + return PumpType.DANA_RV2; } @NonNull @Override diff --git a/danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgHistoryEvents_v2.kt b/danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgHistoryEvents_v2.kt index 3680530833..f6bc47e6b9 100644 --- a/danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgHistoryEvents_v2.kt +++ b/danar/src/main/java/info/nightscout/androidaps/danaRv2/comm/MsgHistoryEvents_v2.kt @@ -10,6 +10,7 @@ import info.nightscout.androidaps.db.Source import info.nightscout.androidaps.db.TemporaryBasal import info.nightscout.androidaps.events.EventPumpStatusChanged import info.nightscout.androidaps.logging.LTag +import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import info.nightscout.androidaps.utils.DateUtil import java.util.* @@ -92,8 +93,8 @@ class MsgHistoryEvents_v2 constructor( info.nightscout.androidaps.dana.DanaPump.BOLUS -> { val detailedBolusInfo = detailedBolusInfoStorage.findDetailedBolusInfo(datetime, param1 / 100.0) ?: DetailedBolusInfo() - detailedBolusInfo.timestamp = datetime - detailedBolusInfo.pumpType = InterfaceIDs.PumpType.DANA_RV2 + detailedBolusInfo.bolusTimestamp = datetime + detailedBolusInfo.pumpType = PumpType.DANA_RV2 detailedBolusInfo.pumpSerial = danaPump.serialNumber detailedBolusInfo.bolusPumpId = datetime detailedBolusInfo.insulin = param1 / 100.0 @@ -105,8 +106,8 @@ class MsgHistoryEvents_v2 constructor( info.nightscout.androidaps.dana.DanaPump.DUALBOLUS -> { val detailedBolusInfo = detailedBolusInfoStorage.findDetailedBolusInfo(datetime, param1 / 100.0) ?: DetailedBolusInfo() - detailedBolusInfo.timestamp = datetime - detailedBolusInfo.pumpType = InterfaceIDs.PumpType.DANA_RV2 + detailedBolusInfo.bolusTimestamp = datetime + detailedBolusInfo.pumpType = PumpType.DANA_RV2 detailedBolusInfo.pumpSerial = danaPump.serialNumber detailedBolusInfo.bolusPumpId = datetime detailedBolusInfo.insulin = param1 / 100.0 @@ -157,8 +158,8 @@ class MsgHistoryEvents_v2 constructor( info.nightscout.androidaps.dana.DanaPump.CARBS -> { val emptyCarbsInfo = DetailedBolusInfo() emptyCarbsInfo.carbs = param1.toDouble() - emptyCarbsInfo.timestamp = datetime - emptyCarbsInfo.pumpType = InterfaceIDs.PumpType.DANA_RV2 + emptyCarbsInfo.carbsTimestamp = datetime + emptyCarbsInfo.pumpType = PumpType.DANA_RV2 emptyCarbsInfo.pumpSerial = danaPump.serialNumber emptyCarbsInfo.carbsPumpId = datetime val newRecord = activePlugin.activeTreatments.addToHistoryTreatment(emptyCarbsInfo, false) diff --git a/danar/src/main/java/info/nightscout/androidaps/danar/DanaRPlugin.java b/danar/src/main/java/info/nightscout/androidaps/danar/DanaRPlugin.java index 406425f6a2..54b32791f9 100644 --- a/danar/src/main/java/info/nightscout/androidaps/danar/DanaRPlugin.java +++ b/danar/src/main/java/info/nightscout/androidaps/danar/DanaRPlugin.java @@ -17,7 +17,6 @@ import info.nightscout.androidaps.danar.services.DanaRExecutionService; import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.PumpEnactResult; -import info.nightscout.androidaps.database.entities.Bolus; import info.nightscout.androidaps.db.ExtendedBolus; import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.db.Treatment; @@ -74,7 +73,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin { this.fabricPrivacy = fabricPrivacy; useExtendedBoluses = sp.getBoolean(R.string.key_danar_useextended, false); - pumpDescription.setPumpDescription(PumpType.DanaR); + pumpDescription.setPumpDescription(PumpType.DANA_R); } @Override @@ -163,7 +162,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin { detailedBolusInfo.insulin = constraintChecker.applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value(); if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) { Treatment t = new Treatment(); - t.isSMB = detailedBolusInfo.getBolusType() == Bolus.Type.SMB; + t.isSMB = detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB; boolean connectionOK = false; if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) connectionOK = sExecutionService.bolus(detailedBolusInfo.insulin, (int) detailedBolusInfo.carbs, detailedBolusInfo.carbTime, t); @@ -324,7 +323,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin { @NonNull @Override public PumpType model() { - return PumpType.DanaR; + return PumpType.DANA_R; } private PumpEnactResult cancelRealTempBasal() { diff --git a/danar/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt b/danar/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt index 97727ab5af..d104302084 100644 --- a/danar/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt +++ b/danar/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt @@ -57,7 +57,7 @@ class TestPumpPlugin(val injector: HasAndroidInjector) : PumpInterface { override fun cancelExtendedBolus(): PumpEnactResult = PumpEnactResult(injector).success(true) override fun getJSONStatus(profile: Profile, profileName: String, version: String): JSONObject = JSONObject() override fun manufacturer(): ManufacturerType = ManufacturerType.AndroidAPS - override fun model(): PumpType = PumpType.GenericAAPS + override fun model(): PumpType = PumpType.GENERIC_AAPS override fun serialNumber(): String = "1" override fun shortStatus(veryShort: Boolean): String = "" override val isFakingTempsByExtendedBoluses: Boolean = false diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/DanaRSPlugin.kt b/danars/src/main/java/info/nightscout/androidaps/danars/DanaRSPlugin.kt index 6f588e4a0d..0add10a2d0 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/DanaRSPlugin.kt +++ b/danars/src/main/java/info/nightscout/androidaps/danars/DanaRSPlugin.kt @@ -15,7 +15,6 @@ import info.nightscout.androidaps.danars.services.DanaRSService import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.Profile import info.nightscout.androidaps.data.PumpEnactResult -import info.nightscout.androidaps.database.entities.Bolus import info.nightscout.androidaps.db.Treatment import info.nightscout.androidaps.events.EventAppExit import info.nightscout.androidaps.events.EventConfigBuilderChange @@ -74,7 +73,7 @@ class DanaRSPlugin @Inject constructor( private var danaRSService: DanaRSService? = null private var mDeviceAddress = "" var mDeviceName = "" - override val pumpDescription = PumpDescription(PumpType.DanaRS) + override val pumpDescription = PumpDescription(PumpType.DANA_RS) override fun updatePreferenceSummary(pref: Preference) { super.updatePreferenceSummary(pref) @@ -280,7 +279,7 @@ class DanaRSPlugin @Inject constructor( detailedBolusInfo.carbTime = 0 detailedBolusInfoStorage.add(detailedBolusInfo) // will be picked up on reading history val t = Treatment() - t.isSMB = detailedBolusInfo.bolusType == Bolus.Type.SMB + t.isSMB = detailedBolusInfo.bolusType == DetailedBolusInfo.BolusType.SMB var connectionOK = false if (detailedBolusInfo.insulin > 0 || carbs > 0) connectionOK = danaRSService?.bolus(detailedBolusInfo.insulin, carbs.toInt(), DateUtil.now() + T.mins(carbTime.toLong()).msecs(), t) ?: false @@ -597,7 +596,7 @@ class DanaRSPlugin @Inject constructor( } override fun model(): PumpType { - return PumpType.DanaRS + return PumpType.DANA_RS } override fun serialNumber(): String { diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_APS_History_Events.kt b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_APS_History_Events.kt index dea76bf3bd..65613641b5 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_APS_History_Events.kt +++ b/danars/src/main/java/info/nightscout/androidaps/danars/comm/DanaRS_Packet_APS_History_Events.kt @@ -6,7 +6,6 @@ import info.nightscout.androidaps.danars.R import info.nightscout.androidaps.danars.encryption.BleEncryption import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.database.AppRepository -import info.nightscout.androidaps.database.embedments.InterfaceIDs import info.nightscout.androidaps.database.entities.TherapyEvent import info.nightscout.androidaps.database.transactions.InsertTherapyEventIfNewTransaction import info.nightscout.androidaps.db.ExtendedBolus @@ -18,6 +17,7 @@ import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.general.nsclient.NSUpload import info.nightscout.androidaps.plugins.pump.common.bolusInfo.DetailedBolusInfoStorage +import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.sharedPreferences.SP @@ -133,8 +133,8 @@ open class DanaRS_Packet_APS_History_Events( DanaPump.BOLUS -> { val detailedBolusInfo = detailedBolusInfoStorage.findDetailedBolusInfo(datetime, param1 / 100.0) ?: DetailedBolusInfo() - detailedBolusInfo.timestamp = datetime - detailedBolusInfo.pumpType = InterfaceIDs.PumpType.DANA_RS + detailedBolusInfo.bolusTimestamp = datetime + detailedBolusInfo.pumpType = PumpType.DANA_RS detailedBolusInfo.pumpSerial = danaPump.serialNumber detailedBolusInfo.bolusPumpId = pumpId detailedBolusInfo.insulin = param1 / 100.0 @@ -146,8 +146,8 @@ open class DanaRS_Packet_APS_History_Events( DanaPump.DUALBOLUS -> { val detailedBolusInfo = detailedBolusInfoStorage.findDetailedBolusInfo(datetime, param1 / 100.0) ?: DetailedBolusInfo() - detailedBolusInfo.timestamp = datetime - detailedBolusInfo.pumpType = InterfaceIDs.PumpType.DANA_RS + detailedBolusInfo.bolusTimestamp = datetime + detailedBolusInfo.pumpType = PumpType.DANA_RS detailedBolusInfo.pumpSerial = danaPump.serialNumber detailedBolusInfo.bolusPumpId = pumpId detailedBolusInfo.insulin = param1 / 100.0 @@ -209,8 +209,8 @@ open class DanaRS_Packet_APS_History_Events( DanaPump.CARBS -> { val emptyCarbsInfo = DetailedBolusInfo() emptyCarbsInfo.carbs = param1.toDouble() - emptyCarbsInfo.timestamp = datetime - emptyCarbsInfo.pumpType = InterfaceIDs.PumpType.DANA_RS + emptyCarbsInfo.carbsTimestamp = datetime + emptyCarbsInfo.pumpType = PumpType.DANA_RS emptyCarbsInfo.pumpSerial = danaPump.serialNumber emptyCarbsInfo.carbsPumpId = pumpId val newRecord = activePlugin.activeTreatments.addToHistoryTreatment(emptyCarbsInfo, false) diff --git a/database/schemas/info.nightscout.androidaps.database.AppDatabase/8.json b/database/schemas/info.nightscout.androidaps.database.AppDatabase/8.json index c03724c9bf..581dafb92f 100644 --- a/database/schemas/info.nightscout.androidaps.database.AppDatabase/8.json +++ b/database/schemas/info.nightscout.androidaps.database.AppDatabase/8.json @@ -2,7 +2,7 @@ "formatVersion": 1, "database": { "version": 8, - "identityHash": "b45eaf7386412002a6289168c3dfa06e", + "identityHash": "c38f6acf42463481d39fe05be1fd3b55", "entities": [ { "tableName": "apsResults", @@ -350,7 +350,7 @@ }, { "tableName": "bolusCalculatorResults", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `targetBGLow` REAL NOT NULL, `targetBGHigh` REAL NOT NULL, `isf` REAL NOT NULL, `ic` REAL NOT NULL, `bolusIOB` REAL NOT NULL, `wasBolusIOBUsed` INTEGER NOT NULL, `basalIOB` REAL NOT NULL, `wasBasalIOBUsed` INTEGER NOT NULL, `glucoseValue` REAL NOT NULL, `wasGlucoseUsed` INTEGER NOT NULL, `glucoseDifference` REAL NOT NULL, `glucoseInsulin` REAL NOT NULL, `glucoseTrend` REAL NOT NULL, `wasTrendUsed` INTEGER NOT NULL, `trendInsulin` REAL NOT NULL, `cob` REAL NOT NULL, `wasCOBUsed` INTEGER NOT NULL, `cobInsulin` REAL NOT NULL, `carbs` REAL NOT NULL, `wereCarbsUsed` INTEGER NOT NULL, `carbsInsulin` REAL NOT NULL, `otherCorrection` REAL NOT NULL, `wasSuperbolusUsed` INTEGER NOT NULL, `superbolusInsulin` REAL NOT NULL, `wasTempTargetUsed` INTEGER NOT NULL, `totalInsulin` REAL NOT NULL, `percentageCorrection` REAL NOT NULL, `profileName` TEXT NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `bolusCalculatorResults`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `targetBGLow` REAL NOT NULL, `targetBGHigh` REAL NOT NULL, `isf` REAL NOT NULL, `ic` REAL NOT NULL, `bolusIOB` REAL NOT NULL, `wasBolusIOBUsed` INTEGER NOT NULL, `basalIOB` REAL NOT NULL, `wasBasalIOBUsed` INTEGER NOT NULL, `glucoseValue` REAL NOT NULL, `wasGlucoseUsed` INTEGER NOT NULL, `glucoseDifference` REAL NOT NULL, `glucoseInsulin` REAL NOT NULL, `glucoseTrend` REAL NOT NULL, `wasTrendUsed` INTEGER NOT NULL, `trendInsulin` REAL NOT NULL, `cob` REAL NOT NULL, `wasCOBUsed` INTEGER NOT NULL, `cobInsulin` REAL NOT NULL, `carbs` REAL NOT NULL, `wereCarbsUsed` INTEGER NOT NULL, `carbsInsulin` REAL NOT NULL, `otherCorrection` REAL NOT NULL, `wasSuperbolusUsed` INTEGER NOT NULL, `superbolusInsulin` REAL NOT NULL, `wasTempTargetUsed` INTEGER NOT NULL, `totalInsulin` REAL NOT NULL, `percentageCorrection` INTEGER NOT NULL, `profileName` TEXT NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `bolusCalculatorResults`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", "fields": [ { "fieldPath": "id", @@ -553,7 +553,7 @@ { "fieldPath": "percentageCorrection", "columnName": "percentageCorrection", - "affinity": "REAL", + "affinity": "INTEGER", "notNull": true }, { @@ -2222,7 +2222,7 @@ }, { "tableName": "mealLinks", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `bolusId` INTEGER, `carbsId` INTEGER, `bolusCalcResultId` INTEGER, `superbolusTempBasalId` INTEGER, `noteId` INTEGER, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`bolusId`) REFERENCES `boluses`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`carbsId`) REFERENCES `carbs`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`bolusCalcResultId`) REFERENCES `bolusCalculatorResults`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`superbolusTempBasalId`) REFERENCES `temporaryBasals`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`noteId`) REFERENCES `therapyEvents`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`referenceId`) REFERENCES `mealLinks`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `bolusId` INTEGER, `carbsId` INTEGER, `bolusCalcResultId` INTEGER, `superbolusTempBasalId` INTEGER, `noteId` INTEGER, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`bolusId`) REFERENCES `boluses`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`carbsId`) REFERENCES `carbs`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`bolusCalcResultId`) REFERENCES `bolusCalculatorResults`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`superbolusTempBasalId`) REFERENCES `temporaryBasals`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`noteId`) REFERENCES `therapyEvents`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`referenceId`) REFERENCES `mealLinks`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", "fields": [ { "fieldPath": "id", @@ -2254,6 +2254,18 @@ "affinity": "INTEGER", "notNull": false }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "utcOffset", + "columnName": "utcOffset", + "affinity": "INTEGER", + "notNull": true + }, { "fieldPath": "bolusId", "columnName": "bolusId", @@ -2930,7 +2942,7 @@ "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'b45eaf7386412002a6289168c3dfa06e')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'c38f6acf42463481d39fe05be1fd3b55')" ] } } \ No newline at end of file diff --git a/database/src/main/java/info/nightscout/androidaps/database/AppRepository.kt b/database/src/main/java/info/nightscout/androidaps/database/AppRepository.kt index b7cc2f707c..20d0a8022f 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/AppRepository.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/AppRepository.kt @@ -1,10 +1,6 @@ package info.nightscout.androidaps.database -import info.nightscout.androidaps.database.entities.Food -import info.nightscout.androidaps.database.entities.GlucoseValue -import info.nightscout.androidaps.database.entities.TemporaryTarget -import info.nightscout.androidaps.database.entities.TherapyEvent -import info.nightscout.androidaps.database.entities.UserEntry +import info.nightscout.androidaps.database.entities.* import info.nightscout.androidaps.database.interfaces.DBEntry import info.nightscout.androidaps.database.transactions.Transaction import io.reactivex.Completable @@ -179,6 +175,28 @@ open class AppRepository @Inject internal constructor( fun deleteAllFoods() = database.foodDao.deleteAllEntries() + // MEAL LINK + fun getMealLinkLoadedDataFromTime(timestamp: Long, ascending: Boolean): Single> = + database.mealLinkDao.getMealLinkLoadedFromTime(timestamp) + .map { if (!ascending) it.reversed() else it } + .subscribeOn(Schedulers.io()) + + fun getMealLinkLoadedDataIncludingInvalidFromTime(timestamp: Long, ascending: Boolean): Single> = + database.mealLinkDao.getMealLinkLoadedIncludingInvalidFromTime(timestamp) + .map { if (!ascending) it.reversed() else it } + .subscribeOn(Schedulers.io()) + + fun deleteAllBoluses() = + database.bolusDao.deleteAllEntries() + + fun deleteAllCarbs() = + database.carbsDao.deleteAllEntries() + + fun deleteAllBolusCalculatorResults() = + database.bolusCalculatorResultDao.deleteAllEntries() + + fun deleteAllMealLinks() = + database.mealLinkDao.deleteAllEntries() } @Suppress("USELESS_CAST") diff --git a/database/src/main/java/info/nightscout/androidaps/database/DatabaseModule.kt b/database/src/main/java/info/nightscout/androidaps/database/DatabaseModule.kt index d2147a6122..14324eda80 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/DatabaseModule.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/DatabaseModule.kt @@ -48,9 +48,18 @@ open class DatabaseModule { private val migration7to8 = object : Migration(7, 8) { override fun migrate(database: SupportSQLiteDatabase) { database.execSQL("DROP TABLE IF EXISTS bolusCalculatorResults") - database.execSQL("CREATE TABLE IF NOT EXISTS bolusCalculatorResults (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `targetBGLow` REAL NOT NULL, `targetBGHigh` REAL NOT NULL, `isf` REAL NOT NULL, `ic` REAL NOT NULL, `bolusIOB` REAL NOT NULL, `wasBolusIOBUsed` INTEGER NOT NULL, `basalIOB` REAL NOT NULL, `wasBasalIOBUsed` INTEGER NOT NULL, `glucoseValue` REAL NOT NULL, `wasGlucoseUsed` INTEGER NOT NULL, `glucoseDifference` REAL NOT NULL, `glucoseInsulin` REAL NOT NULL, `glucoseTrend` REAL NOT NULL, `wasTrendUsed` INTEGER NOT NULL, `trendInsulin` REAL NOT NULL, `cob` REAL NOT NULL, `wasCOBUsed` INTEGER NOT NULL, `cobInsulin` REAL NOT NULL, `carbs` REAL NOT NULL, `wereCarbsUsed` INTEGER NOT NULL, `carbsInsulin` REAL NOT NULL, `otherCorrection` REAL NOT NULL, `wasSuperbolusUsed` INTEGER NOT NULL, `superbolusInsulin` REAL NOT NULL, `wasTempTargetUsed` INTEGER NOT NULL, `totalInsulin` REAL NOT NULL, `percentageCorrection` REAL NOT NULL, `profileName` TEXT NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `bolusCalculatorResults`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )") + database.execSQL("CREATE TABLE IF NOT EXISTS bolusCalculatorResults (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `targetBGLow` REAL NOT NULL, `targetBGHigh` REAL NOT NULL, `isf` REAL NOT NULL, `ic` REAL NOT NULL, `bolusIOB` REAL NOT NULL, `wasBolusIOBUsed` INTEGER NOT NULL, `basalIOB` REAL NOT NULL, `wasBasalIOBUsed` INTEGER NOT NULL, `glucoseValue` REAL NOT NULL, `wasGlucoseUsed` INTEGER NOT NULL, `glucoseDifference` REAL NOT NULL, `glucoseInsulin` REAL NOT NULL, `glucoseTrend` REAL NOT NULL, `wasTrendUsed` INTEGER NOT NULL, `trendInsulin` REAL NOT NULL, `cob` REAL NOT NULL, `wasCOBUsed` INTEGER NOT NULL, `cobInsulin` REAL NOT NULL, `carbs` REAL NOT NULL, `wereCarbsUsed` INTEGER NOT NULL, `carbsInsulin` REAL NOT NULL, `otherCorrection` REAL NOT NULL, `wasSuperbolusUsed` INTEGER NOT NULL, `superbolusInsulin` REAL NOT NULL, `wasTempTargetUsed` INTEGER NOT NULL, `totalInsulin` REAL NOT NULL, `percentageCorrection` INTEGER NOT NULL, `profileName` TEXT NOT NULL, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`referenceId`) REFERENCES `bolusCalculatorResults`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )") database.execSQL("CREATE INDEX IF NOT EXISTS `index_bolusCalculatorResults_referenceId` ON bolusCalculatorResults (`referenceId`)") database.execSQL("CREATE INDEX IF NOT EXISTS `index_bolusCalculatorResults_timestamp` ON bolusCalculatorResults (`timestamp`)") + + database.execSQL("DROP TABLE IF EXISTS mealLinks") + database.execSQL("CREATE TABLE IF NOT EXISTS mealLinks (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `version` INTEGER NOT NULL, `dateCreated` INTEGER NOT NULL, `isValid` INTEGER NOT NULL, `referenceId` INTEGER, `timestamp` INTEGER NOT NULL, `utcOffset` INTEGER NOT NULL, `bolusId` INTEGER, `carbsId` INTEGER, `bolusCalcResultId` INTEGER, `superbolusTempBasalId` INTEGER, `noteId` INTEGER, `nightscoutSystemId` TEXT, `nightscoutId` TEXT, `pumpType` TEXT, `pumpSerial` TEXT, `pumpId` INTEGER, `startId` INTEGER, `endId` INTEGER, FOREIGN KEY(`bolusId`) REFERENCES `boluses`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`carbsId`) REFERENCES `carbs`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`bolusCalcResultId`) REFERENCES `bolusCalculatorResults`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`superbolusTempBasalId`) REFERENCES `temporaryBasals`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`noteId`) REFERENCES `therapyEvents`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`referenceId`) REFERENCES `mealLinks`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )") + database.execSQL("CREATE INDEX IF NOT EXISTS `index_mealLinks_referenceId` ON mealLinks (`referenceId`)") + database.execSQL("CREATE INDEX IF NOT EXISTS `index_mealLinks_bolusId` ON `mealLinks (`bolusId`)") + database.execSQL("CREATE INDEX IF NOT EXISTS `index_mealLinks_carbsId` ON mealLinks (`carbsId`)") + database.execSQL("CREATE INDEX IF NOT EXISTS `index_mealLinks_bolusCalcResultId` ON mealLinks (`bolusCalcResultId`)") + database.execSQL("CREATE INDEX IF NOT EXISTS `index_mealLinks_superbolusTempBasalId` ON mealLinks (`superbolusTempBasalId`)") + database.execSQL("CREATE INDEX IF NOT EXISTS `index_mealLinks_noteId` ON mealLinks (`noteId`)") } } } \ No newline at end of file diff --git a/database/src/main/java/info/nightscout/androidaps/database/daos/MealLinkDao.kt b/database/src/main/java/info/nightscout/androidaps/database/daos/MealLinkDao.kt index 86c6904e30..ef50a0f10a 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/daos/MealLinkDao.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/daos/MealLinkDao.kt @@ -2,8 +2,10 @@ package info.nightscout.androidaps.database.daos import androidx.room.Dao import androidx.room.Query +import androidx.room.Transaction import info.nightscout.androidaps.database.TABLE_MEAL_LINKS import info.nightscout.androidaps.database.entities.MealLink +import info.nightscout.androidaps.database.entities.MealLinkLoaded import io.reactivex.Single @Suppress("FunctionName") @@ -15,4 +17,12 @@ internal interface MealLinkDao : TraceableDao { @Query("DELETE FROM $TABLE_MEAL_LINKS") override fun deleteAllEntries() + + @Transaction + @Query("SELECT * FROM $TABLE_MEAL_LINKS WHERE isValid = 1 AND timestamp >= :timestamp AND referenceId IS NULL ORDER BY id DESC") + fun getMealLinkLoadedFromTime(timestamp: Long): Single> + + @Transaction + @Query("SELECT * FROM $TABLE_MEAL_LINKS WHERE timestamp >= :timestamp AND referenceId IS NULL ORDER BY id DESC") + fun getMealLinkLoadedIncludingInvalidFromTime(timestamp: Long): Single> } \ No newline at end of file diff --git a/database/src/main/java/info/nightscout/androidaps/database/embedments/InterfaceIDs.kt b/database/src/main/java/info/nightscout/androidaps/database/embedments/InterfaceIDs.kt index 4a302fa65d..0f3d10483d 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/embedments/InterfaceIDs.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/embedments/InterfaceIDs.kt @@ -11,15 +11,33 @@ data class InterfaceIDs( ) { enum class PumpType { - USER, - VIRTUAL_PUMP, - ACCU_CHEK_INSIGHT, + GENERIC_AAPS, + CELLNOVO, ACCU_CHEK_COMBO, + ACCU_CHEK_SPIRIT, + ACCU_CHEK_INSIGHT, + ACCU_CHEK_INSIGHT_BLUETOOTH, + ACCU_CHEK_SOLO, + ANIMAS_VIBE, + ANIMAS_PING, DANA_R, + DANA_R_KOREAN, DANA_RV2, DANA_RS, - MEDTRONIC, OMNIPOD_EROS, - OMNIPOD_DASH + OMNIPOD_DASH, + MEDTRONIC_512_517, + MEDTRONIC_515_715, + MEDTRONIC_522_722, + MEDTRONIC_523_723_REVEL, + MEDTRONIC_554_754_VEO, + MEDTRONIC_640G, + TANDEM_T_SLIM, + TANDEM_T_FLEX, + TANDEM_T_SLIM_G4, + TANDEM_T_SLIM_X2, + YPSOPUMP, + MDI, + USER } } \ No newline at end of file diff --git a/database/src/main/java/info/nightscout/androidaps/database/entities/BolusCalculatorResult.kt b/database/src/main/java/info/nightscout/androidaps/database/entities/BolusCalculatorResult.kt index a67ca88e2f..ebc02089d4 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/entities/BolusCalculatorResult.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/entities/BolusCalculatorResult.kt @@ -50,6 +50,6 @@ data class BolusCalculatorResult( var superbolusInsulin: Double, var wasTempTargetUsed: Boolean, var totalInsulin: Double, - var percentageCorrection: Double, + var percentageCorrection: Int, var profileName: String ) : TraceableDBEntry, DBEntryWithTime \ No newline at end of file diff --git a/database/src/main/java/info/nightscout/androidaps/database/entities/Carbs.kt b/database/src/main/java/info/nightscout/androidaps/database/entities/Carbs.kt index 022c0fcadb..cd5a41ab87 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/entities/Carbs.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/entities/Carbs.kt @@ -28,6 +28,6 @@ data class Carbs( override var interfaceIDs_backing: InterfaceIDs? = null, override var timestamp: Long, override var utcOffset: Long = TimeZone.getDefault().getOffset(timestamp).toLong(), - override var duration: Long, + override var duration: Long, // in milliseconds var amount: Double ) : TraceableDBEntry, DBEntryWithTimeAndDuration \ No newline at end of file diff --git a/database/src/main/java/info/nightscout/androidaps/database/entities/MealLink.kt b/database/src/main/java/info/nightscout/androidaps/database/entities/MealLink.kt index 21341213ff..45d8ab75f4 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/entities/MealLink.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/entities/MealLink.kt @@ -3,7 +3,9 @@ package info.nightscout.androidaps.database.entities import androidx.room.* import info.nightscout.androidaps.database.TABLE_MEAL_LINKS import info.nightscout.androidaps.database.embedments.InterfaceIDs +import info.nightscout.androidaps.database.interfaces.DBEntryWithTime import info.nightscout.androidaps.database.interfaces.TraceableDBEntry +import java.util.* @Entity(tableName = TABLE_MEAL_LINKS, foreignKeys = [ @@ -41,6 +43,8 @@ data class MealLink( override var dateCreated: Long = -1, override var isValid: Boolean = true, override var referenceId: Long? = null, + override var timestamp: Long, + override var utcOffset: Long = TimeZone.getDefault().getOffset(timestamp).toLong(), @Embedded override var interfaceIDs_backing: InterfaceIDs? = null, var bolusId: Long? = null, @@ -48,7 +52,8 @@ data class MealLink( var bolusCalcResultId: Long? = null, var superbolusTempBasalId: Long? = null, var noteId: Long? = null -) : TraceableDBEntry { + + ) : TraceableDBEntry, DBEntryWithTime { override val foreignKeysValid: Boolean get() = super.foreignKeysValid && bolusId != 0L && carbsId != 0L && diff --git a/database/src/main/java/info/nightscout/androidaps/database/entities/MealLinkLoaded.kt b/database/src/main/java/info/nightscout/androidaps/database/entities/MealLinkLoaded.kt new file mode 100644 index 0000000000..82e46d79f2 --- /dev/null +++ b/database/src/main/java/info/nightscout/androidaps/database/entities/MealLinkLoaded.kt @@ -0,0 +1,33 @@ +package info.nightscout.androidaps.database.entities + +import androidx.room.Embedded +import androidx.room.Relation + +data class MealLinkLoaded constructor( + @Embedded val mealLink: MealLink, + @Relation( + entity = Bolus::class, + parentColumn = "bolusId", + entityColumn = "id") + val bolus: Bolus?, + @Relation( + entity = Carbs::class, + parentColumn = "carbsId", + entityColumn = "id") + val carbs: Carbs?, + @Relation( + entity = BolusCalculatorResult::class, + parentColumn = "bolusCalcResultId", + entityColumn = "id") + val bolusCalculatorResult: BolusCalculatorResult?, + @Relation( + entity = TemporaryBasal::class, + parentColumn = "superbolusTempBasalId", + entityColumn = "id") + val superBolusTemporaryBasal: TemporaryBasal?, + @Relation( + entity = TherapyEvent::class, + parentColumn = "noteId", + entityColumn = "id") + val therapyEvent: TherapyEvent? +) \ No newline at end of file diff --git a/database/src/main/java/info/nightscout/androidaps/database/transactions/InsertMealLinkTransaction.kt b/database/src/main/java/info/nightscout/androidaps/database/transactions/InsertMealLinkTransaction.kt index 4a1d4505d4..f145081dd0 100644 --- a/database/src/main/java/info/nightscout/androidaps/database/transactions/InsertMealLinkTransaction.kt +++ b/database/src/main/java/info/nightscout/androidaps/database/transactions/InsertMealLinkTransaction.kt @@ -23,6 +23,7 @@ class InsertMealLinkTransaction( val therapyEventId = if (therapyEvent != null) database.therapyEventDao.insert(therapyEvent) else null val mealLink = MealLink( + timestamp = System.currentTimeMillis(), bolusId = bolusId, carbsId = carbsId, bolusCalcResultId = bolusCalculatorResultId, @@ -31,13 +32,14 @@ class InsertMealLinkTransaction( ) database.mealLinkDao.insert(mealLink) - result.inserted.add(mealLink) + val full = MealLinkLoaded(mealLink, bolus, carbs, bolusCalculatorResult, superBolusTemporaryBasal, therapyEvent) + result.inserted.add(full) return result } class TransactionResult { - val inserted = mutableListOf() + val inserted = mutableListOf() } } \ No newline at end of file diff --git a/database/src/main/java/info/nightscout/androidaps/database/transactions/InvalidateBolusTransaction.kt b/database/src/main/java/info/nightscout/androidaps/database/transactions/InvalidateBolusTransaction.kt new file mode 100644 index 0000000000..8824690ff8 --- /dev/null +++ b/database/src/main/java/info/nightscout/androidaps/database/transactions/InvalidateBolusTransaction.kt @@ -0,0 +1,11 @@ +package info.nightscout.androidaps.database.transactions + +class InvalidateBolusTransaction(val id: Long) : Transaction() { + + override fun run() { + val bolus = database.bolusDao.findById(id) + ?: throw IllegalArgumentException("There is no such Bolus with the specified ID.") + bolus.isValid = false + database.bolusDao.updateExistingEntry(bolus) + } +} \ No newline at end of file diff --git a/database/src/main/java/info/nightscout/androidaps/database/transactions/InvalidateCarbsTransaction.kt b/database/src/main/java/info/nightscout/androidaps/database/transactions/InvalidateCarbsTransaction.kt new file mode 100644 index 0000000000..70646231bc --- /dev/null +++ b/database/src/main/java/info/nightscout/androidaps/database/transactions/InvalidateCarbsTransaction.kt @@ -0,0 +1,11 @@ +package info.nightscout.androidaps.database.transactions + +class InvalidateCarbsTransaction(val id: Long) : Transaction() { + + override fun run() { + val carbs = database.carbsDao.findById(id) + ?: throw IllegalArgumentException("There is no such Carbs with the specified ID.") + carbs.isValid = false + database.carbsDao.updateExistingEntry(carbs) + } +} \ No newline at end of file diff --git a/database/src/main/java/info/nightscout/androidaps/database/transactions/InvalidateMealLinkTransaction.kt b/database/src/main/java/info/nightscout/androidaps/database/transactions/InvalidateMealLinkTransaction.kt new file mode 100644 index 0000000000..631260bdd1 --- /dev/null +++ b/database/src/main/java/info/nightscout/androidaps/database/transactions/InvalidateMealLinkTransaction.kt @@ -0,0 +1,42 @@ +package info.nightscout.androidaps.database.transactions + +class InvalidateMealLinkTransaction(val id: Long) : Transaction() { + + override fun run() { + val mealLink = database.mealLinkDao.findById(id) + ?: throw IllegalArgumentException("There is no such MealLink with the specified ID.") + + if (mealLink.bolusId != null) { + val bolus = database.bolusDao.findById(id) + ?: throw IllegalArgumentException("There is no such Bolus with the specified ID.") + bolus.isValid = false + database.bolusDao.updateExistingEntry(bolus) + } + + if (mealLink.carbsId != null) { + val carbs = database.carbsDao.findById(id) + ?: throw IllegalArgumentException("There is no such Carbs with the specified ID.") + carbs.isValid = false + database.carbsDao.updateExistingEntry(carbs) + } + + if (mealLink.bolusCalcResultId != null) { + val bolusCalculatorResult = database.bolusCalculatorResultDao.findById(id) + ?: throw IllegalArgumentException("There is no such BolusCalculatorResult with the specified ID.") + bolusCalculatorResult.isValid = false + database.bolusCalculatorResultDao.updateExistingEntry(bolusCalculatorResult) + } + + // TemporaryBasal is not invalidated for safety reason + + if (mealLink.noteId != null) { + val therapyEvent = database.therapyEventDao.findById(id) + ?: throw IllegalArgumentException("There is no such TherapyEvent with the specified ID.") + therapyEvent.isValid = false + database.therapyEventDao.updateExistingEntry(therapyEvent) + } + + mealLink.isValid = false + database.mealLinkDao.updateExistingEntry(mealLink) + } +} \ No newline at end of file diff --git a/insight/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java b/insight/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java index 022ba9ae99..ba51e070b7 100644 --- a/insight/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java +++ b/insight/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java @@ -31,8 +31,6 @@ import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.database.AppRepository; -import info.nightscout.androidaps.database.embedments.InterfaceIDs; -import info.nightscout.androidaps.database.entities.Bolus; import info.nightscout.androidaps.database.entities.TherapyEvent; import info.nightscout.androidaps.database.transactions.InsertTherapyEventIfNewTransaction; import info.nightscout.androidaps.db.ExtendedBolus; @@ -247,7 +245,7 @@ public class LocalInsightPlugin extends PumpPluginBase implements PumpInterface, this.repository = repository; pumpDescription = new PumpDescription(); - pumpDescription.setPumpDescription(PumpType.AccuChekInsightBluetooth); + pumpDescription.setPumpDescription(PumpType.ACCU_CHEK_INSIGHT_BLUETOOTH); } public TBROverNotificationBlock getTBROverNotificationBlock() { @@ -593,13 +591,13 @@ public class LocalInsightPlugin extends PumpPluginBase implements PumpInterface, bolusMessage.setDuration(0); bolusMessage.setExtendedAmount(0); bolusMessage.setImmediateAmount(insulin); - bolusMessage.setVibration(sp.getBoolean(detailedBolusInfo.getBolusType() == Bolus.Type.SMB ? R.string.key_disable_vibration_auto : R.string.key_disable_vibration, false)); + bolusMessage.setVibration(sp.getBoolean(detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB ? R.string.key_disable_vibration_auto : R.string.key_disable_vibration, false)); bolusID = connectionService.requestMessage(bolusMessage).await().getBolusId(); bolusCancelled = false; } result.success(true).enacted(true); Treatment t = new Treatment(); - t.isSMB = detailedBolusInfo.getBolusType() == Bolus.Type.SMB; + t.isSMB = detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB; final EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.INSTANCE; bolusingEvent.setT(t); bolusingEvent.setStatus(resourceHelper.gs(R.string.insight_delivered, 0d, insulin)); @@ -611,15 +609,15 @@ public class LocalInsightPlugin extends PumpPluginBase implements PumpInterface, insightBolusID.timestamp = System.currentTimeMillis(); insightBolusID.pumpSerial = connectionService.getPumpSystemIdentification().getSerialNumber(); databaseHelper.createOrUpdate(insightBolusID); - detailedBolusInfo.timestamp = insightBolusID.timestamp; - detailedBolusInfo.setPumpType(InterfaceIDs.PumpType.ACCU_CHEK_INSIGHT); + detailedBolusInfo.setBolusTimestamp(insightBolusID.timestamp); + detailedBolusInfo.setPumpType(PumpType.ACCU_CHEK_INSIGHT); detailedBolusInfo.setPumpSerial(serialNumber()); detailedBolusInfo.setBolusPumpId(insightBolusID.id); if (detailedBolusInfo.carbs > 0 && detailedBolusInfo.carbTime != 0) { DetailedBolusInfo carbInfo = new DetailedBolusInfo(); carbInfo.carbs = detailedBolusInfo.carbs; - carbInfo.timestamp = detailedBolusInfo.timestamp + detailedBolusInfo.carbTime * 60L * 1000L; - carbInfo.setPumpType(InterfaceIDs.PumpType.USER); + carbInfo.setCarbsTimestamp(detailedBolusInfo.timestamp + detailedBolusInfo.carbTime * 60L * 1000L); + carbInfo.setPumpType(PumpType.USER); treatmentsPlugin.addToHistoryTreatment(carbInfo, false); detailedBolusInfo.carbTime = 0; detailedBolusInfo.carbs = 0; @@ -1033,7 +1031,7 @@ public class LocalInsightPlugin extends PumpPluginBase implements PumpInterface, @NonNull @Override public PumpType model() { - return PumpType.AccuChekInsightBluetooth; + return PumpType.ACCU_CHEK_INSIGHT_BLUETOOTH; } @NonNull @Override @@ -1394,7 +1392,7 @@ public class LocalInsightPlugin extends PumpPluginBase implements PumpInterface, if (event.getBolusType() == BolusType.STANDARD || event.getBolusType() == BolusType.MULTIWAVE) { DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); detailedBolusInfo.timestamp = bolusID.timestamp; - detailedBolusInfo.setPumpType(InterfaceIDs.PumpType.ACCU_CHEK_INSIGHT); + detailedBolusInfo.setPumpType(PumpType.ACCU_CHEK_INSIGHT); detailedBolusInfo.setPumpSerial(serialNumber()); detailedBolusInfo.setBolusPumpId(bolusID.id); detailedBolusInfo.insulin = event.getImmediateAmount(); @@ -1428,8 +1426,8 @@ public class LocalInsightPlugin extends PumpPluginBase implements PumpInterface, databaseHelper.createOrUpdate(bolusID); if (event.getBolusType() == BolusType.STANDARD || event.getBolusType() == BolusType.MULTIWAVE) { DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); - detailedBolusInfo.timestamp = bolusID.timestamp; - detailedBolusInfo.setPumpType(InterfaceIDs.PumpType.ACCU_CHEK_INSIGHT); + detailedBolusInfo.setBolusTimestamp(bolusID.timestamp); + detailedBolusInfo.setPumpType(PumpType.ACCU_CHEK_INSIGHT); detailedBolusInfo.setPumpSerial(serialNumber()); detailedBolusInfo.setBolusPumpId(bolusID.id); detailedBolusInfo.insulin = event.getImmediateAmount(); diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.java b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.java index 9a992ab69d..b06b75300c 100644 --- a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.java +++ b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.java @@ -151,7 +151,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter .shortName(R.string.medtronic_name_short) // .preferencesId(R.xml.pref_medtronic) .description(R.string.description_pump_medtronic), // - PumpType.Medtronic_522_722, // we default to most basic model, correct model from config is loaded later + PumpType.MEDTRONIC_522_722, // we default to most basic model, correct model from config is loaded later injector, resourceHelper, aapsLogger, commandQueue, rxBus, activePlugin, sp, context, fabricPrivacy, dateUtil, aapsSchedulers ); @@ -888,7 +888,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter // we subtract insulin, exact amount will be visible with next remainingInsulin update. medtronicPumpStatus.reservoirRemainingUnits -= detailedBolusInfo.insulin; - incrementStatistics(detailedBolusInfo.getBolusType() == Bolus.Type.SMB ? MedtronicConst.Statistics.SMBBoluses + incrementStatistics(detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB ? MedtronicConst.Statistics.SMBBoluses : MedtronicConst.Statistics.StandardBoluses); diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryData.java b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryData.java index 67bdac6d70..55dcac045f 100644 --- a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryData.java +++ b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryData.java @@ -22,7 +22,6 @@ import javax.inject.Singleton; import dagger.android.HasAndroidInjector; import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.database.AppRepository; -import info.nightscout.androidaps.database.embedments.InterfaceIDs; import info.nightscout.androidaps.database.entities.TherapyEvent; import info.nightscout.androidaps.database.transactions.InsertTherapyEventIfNewTransaction; import info.nightscout.androidaps.db.DbObjectBase; @@ -986,8 +985,8 @@ public class MedtronicHistoryData { case Normal: { DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); - detailedBolusInfo.timestamp = tryToGetByLocalTime(bolus.atechDateTime); - detailedBolusInfo.setPumpType(InterfaceIDs.PumpType.MEDTRONIC); + detailedBolusInfo.setBolusTimestamp(tryToGetByLocalTime(bolus.atechDateTime)); + detailedBolusInfo.setPumpType(PumpType.MEDTRONIC_512_712); // TODO grab real model detailedBolusInfo.setPumpSerial(medtronicPumpStatus.serialNumber); detailedBolusInfo.setBolusPumpId(bolus.getPumpId()); detailedBolusInfo.insulin = bolusDTO.getDeliveredAmount(); diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/driver/MedtronicPumpStatus.java b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/driver/MedtronicPumpStatus.java index 870bbe273d..905a005e29 100644 --- a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/driver/MedtronicPumpStatus.java +++ b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/driver/MedtronicPumpStatus.java @@ -65,7 +65,7 @@ public class MedtronicPumpStatus extends info.nightscout.androidaps.plugins.pump RxBusWrapper rxBus, RileyLinkUtil rileyLinkUtil ) { - super(PumpType.Medtronic_522_722); + super(PumpType.MEDTRONIC_522_722); this.resourceHelper = resourceHelper; this.sp = sp; this.rxBus = rxBus; @@ -110,17 +110,17 @@ public class MedtronicPumpStatus extends info.nightscout.androidaps.plugins.pump private void createMedtronicPumpMap() { medtronicPumpMap = new HashMap<>(); - medtronicPumpMap.put("512", PumpType.Medtronic_512_712); - medtronicPumpMap.put("712", PumpType.Medtronic_512_712); - medtronicPumpMap.put("515", PumpType.Medtronic_515_715); - medtronicPumpMap.put("715", PumpType.Medtronic_515_715); + medtronicPumpMap.put("512", PumpType.MEDTRONIC_512_712); + medtronicPumpMap.put("712", PumpType.MEDTRONIC_512_712); + medtronicPumpMap.put("515", PumpType.MEDTRONIC_515_715); + medtronicPumpMap.put("715", PumpType.MEDTRONIC_515_715); - medtronicPumpMap.put("522", PumpType.Medtronic_522_722); - medtronicPumpMap.put("722", PumpType.Medtronic_522_722); - medtronicPumpMap.put("523", PumpType.Medtronic_523_723_Revel); - medtronicPumpMap.put("723", PumpType.Medtronic_523_723_Revel); - medtronicPumpMap.put("554", PumpType.Medtronic_554_754_Veo); - medtronicPumpMap.put("754", PumpType.Medtronic_554_754_Veo); + medtronicPumpMap.put("522", PumpType.MEDTRONIC_522_722); + medtronicPumpMap.put("722", PumpType.MEDTRONIC_522_722); + medtronicPumpMap.put("523", PumpType.MEDTRONIC_523_723_REVEL); + medtronicPumpMap.put("723", PumpType.MEDTRONIC_523_723_REVEL); + medtronicPumpMap.put("554", PumpType.MEDTRONIC_554_754_VEO); + medtronicPumpMap.put("754", PumpType.MEDTRONIC_554_754_VEO); } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.java b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.java index b62959e4f4..e21daf9899 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.java +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.java @@ -34,7 +34,7 @@ import info.nightscout.androidaps.utils.resources.ResourceHelper; @Singleton public class OmnipodDashPumpPlugin extends PumpPluginBase implements PumpInterface { - private static final PumpDescription PUMP_DESCRIPTION = new PumpDescription(PumpType.Omnipod_Dash); + private static final PumpDescription PUMP_DESCRIPTION = new PumpDescription(PumpType.OMNIPOD_DASH); private final AAPSLogger aapsLogger; private final ResourceHelper resourceHelper; diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPlugin.java b/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPlugin.java index a3a2f448d8..50cd86038c 100644 --- a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPlugin.java +++ b/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPlugin.java @@ -140,7 +140,7 @@ public class OmnipodErosPumpPlugin extends PumpPluginBase implements PumpInterfa private final DateUtil dateUtil; private final PumpDescription pumpDescription; private final ServiceConnection serviceConnection; - private final PumpType pumpType = PumpType.Omnipod_Eros; + private final PumpType pumpType = PumpType.OMNIPOD_EROS; private final CompositeDisposable disposables = new CompositeDisposable(); private final NSUpload nsUpload; @@ -1086,7 +1086,7 @@ public class OmnipodErosPumpPlugin extends PumpPluginBase implements PumpInterfa PumpEnactResult result = executeCommand(OmnipodCommandType.SET_BOLUS, () -> aapsOmnipodErosManager.bolus(detailedBolusInfo)); if (result.getSuccess()) { - incrementStatistics(detailedBolusInfo.getBolusType() == Bolus.Type.SMB ? OmnipodErosStorageKeys.Statistics.SMB_BOLUSES_DELIVERED + incrementStatistics(detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB ? OmnipodErosStorageKeys.Statistics.SMB_BOLUSES_DELIVERED : OmnipodErosStorageKeys.Statistics.STANDARD_BOLUSES_DELIVERED); result.carbsDelivered(detailedBolusInfo.carbs); diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsOmnipodErosManager.java b/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsOmnipodErosManager.java index 79365c3f2d..2e68985b08 100644 --- a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsOmnipodErosManager.java +++ b/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsOmnipodErosManager.java @@ -19,8 +19,6 @@ import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.database.AppRepository; -import info.nightscout.androidaps.database.embedments.InterfaceIDs; -import info.nightscout.androidaps.database.entities.Bolus; import info.nightscout.androidaps.database.entities.TherapyEvent; import info.nightscout.androidaps.database.transactions.InsertTherapyEventIfNewTransaction; import info.nightscout.androidaps.db.OmnipodHistoryRecord; @@ -374,11 +372,11 @@ public class AapsOmnipodErosManager { public PumpEnactResult bolus(DetailedBolusInfo detailedBolusInfo) { OmnipodManager.BolusCommandResult bolusCommandResult; - boolean beepsEnabled = detailedBolusInfo.getBolusType() == Bolus.Type.SMB ? isSmbBeepsEnabled() : isBolusBeepsEnabled(); + boolean beepsEnabled = detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB ? isSmbBeepsEnabled() : isBolusBeepsEnabled(); Date bolusStarted; try { - bolusCommandResult = executeCommand(() -> delegate.bolus(PumpType.Omnipod_Eros.determineCorrectBolusSize(detailedBolusInfo.insulin), beepsEnabled, beepsEnabled, detailedBolusInfo.getBolusType() == Bolus.Type.SMB ? null : + bolusCommandResult = executeCommand(() -> delegate.bolus(PumpType.OMNIPOD_EROS.determineCorrectBolusSize(detailedBolusInfo.insulin), beepsEnabled, beepsEnabled, detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB ? null : (estimatedUnitsDelivered, percentage) -> { EventOverviewBolusProgress progressUpdateEvent = EventOverviewBolusProgress.INSTANCE; progressUpdateEvent.setStatus(getStringResource(R.string.bolusdelivering, detailedBolusInfo.insulin)); @@ -395,7 +393,7 @@ public class AapsOmnipodErosManager { 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 - if (detailedBolusInfo.getBolusType() == Bolus.Type.SMB) { + if (detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB) { showNotification(Notification.OMNIPOD_UNCERTAIN_SMB, getStringResource(R.string.omnipod_eros_error_bolus_failed_uncertain_smb, detailedBolusInfo.insulin), Notification.URGENT, isNotificationUncertainSmbSoundEnabled() ? R.raw.boluserror : null); } else { showErrorDialog(getStringResource(R.string.omnipod_eros_error_bolus_failed_uncertain), isNotificationUncertainBolusSoundEnabled() ? R.raw.boluserror : null); @@ -403,7 +401,7 @@ public class AapsOmnipodErosManager { } detailedBolusInfo.timestamp = bolusStarted.getTime(); - detailedBolusInfo.setPumpType(InterfaceIDs.PumpType.OMNIPOD_EROS); + detailedBolusInfo.setPumpType(PumpType.OMNIPOD_EROS); detailedBolusInfo.setPumpSerial(serialNumber()); // Store the current bolus for in case the app crashes, gets killed, the phone dies or whatever before the bolus finishes @@ -490,7 +488,7 @@ public class AapsOmnipodErosManager { public PumpEnactResult setTemporaryBasal(TempBasalPair tempBasalPair) { boolean beepsEnabled = isTbrBeepsEnabled(); try { - executeCommand(() -> delegate.setTemporaryBasal(PumpType.Omnipod_Eros.determineCorrectBasalSize(tempBasalPair.getInsulinRate()), Duration.standardMinutes(tempBasalPair.getDurationMinutes()), beepsEnabled, beepsEnabled)); + executeCommand(() -> delegate.setTemporaryBasal(PumpType.OMNIPOD_EROS.determineCorrectBasalSize(tempBasalPair.getInsulinRate()), Duration.standardMinutes(tempBasalPair.getDurationMinutes()), beepsEnabled, beepsEnabled)); } catch (CommandFailedAfterChangingDeliveryStatusException ex) { String errorMessage = translateException(ex.getCause()); addFailureToHistory(PodHistoryEntryType.SET_TEMPORARY_BASAL, errorMessage); @@ -532,7 +530,7 @@ public class AapsOmnipodErosManager { return new PumpEnactResult(injector) .duration(tempBasalPair.getDurationMinutes()) - .absolute(PumpType.Omnipod_Eros.determineCorrectBasalSize(tempBasalPair.getInsulinRate())) + .absolute(PumpType.OMNIPOD_EROS.determineCorrectBasalSize(tempBasalPair.getInsulinRate())) .success(true).enacted(true); } @@ -705,16 +703,17 @@ public class AapsOmnipodErosManager { public void addBolusToHistory(DetailedBolusInfo originalDetailedBolusInfo) { DetailedBolusInfo detailedBolusInfo = originalDetailedBolusInfo.copy(); - detailedBolusInfo.setPumpType(InterfaceIDs.PumpType.OMNIPOD_EROS); + detailedBolusInfo.setBolusTimestamp(detailedBolusInfo.timestamp); + detailedBolusInfo.setPumpType(PumpType.OMNIPOD_EROS); detailedBolusInfo.setPumpSerial(serialNumber()); detailedBolusInfo.setBolusPumpId(addSuccessToHistory(detailedBolusInfo.timestamp, PodHistoryEntryType.SET_BOLUS, detailedBolusInfo.insulin + ";" + detailedBolusInfo.carbs)); if (detailedBolusInfo.carbs > 0 && detailedBolusInfo.carbTime > 0) { // split out a separate carbs record without a pumpId DetailedBolusInfo carbInfo = new DetailedBolusInfo(); - carbInfo.timestamp = detailedBolusInfo.timestamp + detailedBolusInfo.carbTime * 60L * 1000L; + carbInfo.setCarbsTimestamp(detailedBolusInfo.timestamp + detailedBolusInfo.carbTime * 60L * 1000L); carbInfo.carbs = detailedBolusInfo.carbs; - carbInfo.setPumpType(InterfaceIDs.PumpType.USER); + carbInfo.setPumpType(PumpType.USER); activePlugin.getActiveTreatments().addToHistoryTreatment(carbInfo, false); // remove carbs from bolusInfo to not trigger any unwanted code paths in @@ -997,7 +996,7 @@ public class AapsOmnipodErosManager { } List entries = new ArrayList<>(); for (Profile.ProfileValue basalValue : basalValues) { - entries.add(new BasalScheduleEntry(PumpType.Omnipod_Eros.determineCorrectBasalSize(basalValue.value), + entries.add(new BasalScheduleEntry(PumpType.OMNIPOD_EROS.determineCorrectBasalSize(basalValue.value), Duration.standardSeconds(basalValue.timeAsSeconds))); } diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/ErosPodHistoryActivity.java b/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/ErosPodHistoryActivity.java index 77a71f6714..3e55a2bf12 100644 --- a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/ErosPodHistoryActivity.java +++ b/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/ui/ErosPodHistoryActivity.java @@ -309,7 +309,7 @@ public class ErosPodHistoryActivity extends NoSplashAppCompatActivity { try { Profile.ProfileValue[] profileValuesArray = aapsOmnipodUtil.getGsonInstance().fromJson(data, Profile.ProfileValue[].class); - valueView.setText(ProfileUtil.getBasalProfilesDisplayable(profileValuesArray, PumpType.Omnipod_Eros)); + valueView.setText(ProfileUtil.getBasalProfilesDisplayable(profileValuesArray, PumpType.OMNIPOD_EROS)); } catch (Exception e) { aapsLogger.error(LTag.PUMP, "Problem parsing Profile json. Ex: {}, Data:\n{}", e.getMessage(), data); valueView.setText(""); diff --git a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPluginTest.java b/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPluginTest.java index 0d09c36f57..ffe2160f06 100644 --- a/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPluginTest.java +++ b/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPluginTest.java @@ -30,7 +30,6 @@ import info.nightscout.androidaps.plugins.pump.omnipod.eros.manager.AapsOmnipodE import info.nightscout.androidaps.utils.resources.ResourceHelper; import info.nightscout.androidaps.utils.rx.TestAapsSchedulers; -import static info.nightscout.androidaps.plugins.pump.omnipod.eros.driver.definition.OmnipodConstants.BASAL_STEP_DURATION; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; @@ -124,7 +123,7 @@ public class OmnipodErosPumpPluginTest { // When treatment result1 = plugin.setTempBasalPercent(80, 30, profile, false); // Then return sane values - assertEquals(result1.getAbsolute(), PumpType.Omnipod_Eros.determineCorrectBasalSize(500d * 0.8), 0.01d); + assertEquals(result1.getAbsolute(), PumpType.OMNIPOD_EROS.determineCorrectBasalSize(500d * 0.8), 0.01d); assertEquals(result1.getDuration(), 30); // Given weird basal