DetailedBolusInfo, MealLink UI

This commit is contained in:
Milos Kozak 2021-03-25 17:48:07 +01:00
parent 616871c95c
commit 7f0fe881b6
94 changed files with 1741 additions and 1358 deletions

View file

@ -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() + '"'

View file

@ -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<Carbs>().firstOrNull()?.let {
aapsLogger.debug(LTag.DATABASE, "Firing EventFoodDatabaseChanged")
rxBus.send(EventTreatmentChange(null))
}
it.filterIsInstance<Bolus>().firstOrNull()?.let {
aapsLogger.debug(LTag.DATABASE, "Firing EventFoodDatabaseChanged")
rxBus.send(EventTreatmentChange(null))
}
}
}

View file

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

View file

@ -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())

View file

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

View file

@ -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() {

View file

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

View file

@ -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("<br/>").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

View file

@ -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,

View file

@ -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() {

View file

@ -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)

View file

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

View file

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

View file

@ -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(), "%")
}
}

View file

@ -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()

View file

@ -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 {

View file

@ -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) {

View file

@ -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<LoopPlugin>,
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)
}
}

View file

@ -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()

View file

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

View file

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

View file

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

View file

@ -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()) {

View file

@ -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<Treatment>) : RecyclerView.Adapter<TreatmentsViewHolder>() {
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
}
}

View file

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

View file

@ -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<MealLinkLoaded>) : RecyclerView.Adapter<RecyclerViewAdapter.MealLinkLoadedViewHolder>() {
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
}
}
}
}

View file

@ -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))

View file

@ -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<String> = 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) {

View file

@ -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")
}

View file

@ -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" />
</LinearLayout>

View file

@ -1,53 +1,11 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".plugins.treatments.fragments.TreatmentsBolusFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingTop="10dp"
android:paddingBottom="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="10dp"
android:text="@string/treatments_iobtotal_label_string"
android:textAppearance="?android:attr/textAppearanceSmall"
tools:ignore="RtlSymmetry" />
<TextView
android:id="@+id/iob_total"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="10dp"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textStyle="bold"
tools:ignore="RtlSymmetry" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="10dp"
android:text="@string/treatments_iobactivitytotal_label_string"
android:textAppearance="?android:attr/textAppearanceSmall"
tools:ignore="RtlSymmetry" />
<TextView
android:id="@+id/iob_activity_total"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="10dp"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textStyle="bold"
tools:ignore="RtlSymmetry" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -57,7 +15,7 @@
android:id="@+id/refresh_from_nightscout"
style="?android:attr/buttonStyle"
android:layout_width="0px"
android:layout_height="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
android:drawableStart="@drawable/ic_refresh"
@ -67,12 +25,28 @@
android:id="@+id/delete_future_treatments"
style="?android:attr/buttonStyle"
android:layout_width="0px"
android:layout_height="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
android:drawableStart="@drawable/ic_remove"
android:text="@string/deletefuturetreatments" />
<CheckBox
android:id="@+id/show_invalidated"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|center_vertical"
android:checked="false"
android:paddingEnd="5dp"
tools:ignore="RtlSymmetry" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:contentDescription="@string/show_removed"
app:srcCompat="@drawable/ic_visibility" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView

View file

@ -22,8 +22,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="5dp"
android:gravity="center"
android:paddingStart="10dp"
android:text="{fa-clock-o}"
tools:ignore="HardcodedText,RtlSymmetry" />
@ -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" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:text="@string/treatments_iob_label_string" />
<TextView
android:id="@+id/iob"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="10dp"
android:textStyle="bold" />
<TextView
android:id="@+id/meal_or_correction"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:layout_weight="1"
android:text="" />
<TextView
android:id="@+id/calculation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:text="@string/calculation_short"
android:textAlignment="viewEnd"
android:textColor="@color/colorCalculatorButton"
tools:ignore="RtlSymmetry" />
<TextView
android:id="@+id/meal_or_correction"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:text="Meal"
android:textAlignment="textEnd"
tools:ignore="HardcodedText" />
@ -48,16 +81,34 @@
</LinearLayout>
<LinearLayout
android:id="@+id/bolus_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<com.joanzapata.iconify.widget.IconTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="15dp"
android:gravity="center"
android:text="{fa-clock-o}"
tools:ignore="HardcodedText,RtlSymmetry" />
<TextView
android:id="@+id/bolus_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:text="1.1.2000"
tools:ignore="HardcodedText,RtlSymmetry" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:text="@string/treatments_insulin_label_string" />
<TextView
@ -68,12 +119,79 @@
android:layout_marginEnd="30dp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:layout_weight="1"
android:text="" />
<TextView
android:id="@+id/bolus_ns"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:text="NS"
android:textColor="@color/colorSetTempButton"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/bolus_pump"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:text="PH"
android:textColor="@color/colorSetTempButton"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/bolus_invalid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:text="@string/invalid"
android:textColor="@android:color/holo_red_light" />
<TextView
android:id="@+id/bolus_remove"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:text="@string/remove_button"
android:textAlignment="viewEnd"
android:textColor="@android:color/holo_orange_light" />
</LinearLayout>
<LinearLayout
android:id="@+id/carbs_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<com.joanzapata.iconify.widget.IconTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="15dp"
android:gravity="center"
android:text="{fa-clock-o}"
tools:ignore="HardcodedText,RtlSymmetry" />
<TextView
android:id="@+id/carbs_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:text="1.1.2000"
tools:ignore="HardcodedText,RtlSymmetry" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:text="@string/treatments_carbs_label_string" />
<TextView
@ -91,16 +209,7 @@
android:text="" />
<TextView
android:id="@+id/pump"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:text="PH"
android:textColor="@color/colorSetTempButton"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/ns"
android:id="@+id/carbs_ns"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
@ -109,57 +218,24 @@
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/invalid"
android:id="@+id/carbs_pump"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:text="PH"
android:textColor="@color/colorSetTempButton"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/carbs_invalid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:text="@string/invalid"
android:textColor="@android:color/holo_red_light" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="@string/treatments_iob_label_string" />
<TextView
android:id="@+id/iob"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="30dp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="30dp"
android:textStyle="bold" />
<TextView
android:id="@+id/calculation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:layout_weight="1"
android:paddingEnd="10dp"
android:text="@string/calculation_short"
android:textAlignment="viewEnd"
android:textColor="@color/colorCalculatorButton"
tools:ignore="RtlSymmetry" />
<TextView
android:id="@+id/remove"
android:id="@+id/carbs_remove"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"

View file

@ -35,7 +35,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" />

View file

@ -978,6 +978,7 @@
<string name="randombg_short">BG</string>
<string name="tools">Tools</string>
<string name="show_calculation">Show calcuation</string>
<string name="show_removed">Show removed</string>
<string name="clearqueueconfirm">Clear queue? All data in queue will be lost!</string>
<string name="key_xdripstatus_detailediob" translatable="false">xdripstatus_detailediob</string>
<string name="key_xdripstatus_showbgi" translatable="false">xdripstatus_showbgi</string>

View file

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

View file

@ -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)

View file

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

View file

@ -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))

View file

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

View file

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

View file

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

View file

@ -422,7 +422,7 @@ class TDDStatsActivity : NoSplashAppCompatActivity() {
private fun isOldData(historyList: List<TDD>): 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))
}

View file

@ -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)

View file

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

View file

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

View file

@ -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<ValueWithUnit>()
for (v in listvalues){
for (v in listValues){
if (v.condition) values.add(v)
}
compositeDisposable += repository.runTransaction(UserEntryTransaction(

View file

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

View file

@ -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")

View file

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

View file

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

View file

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

View file

@ -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)

View file

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

View file

@ -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<PumpCapability> = ArrayList()
constructor() { children.add(this)}
constructor(list: Array<PumpCapability>) {
children.addAll(list)
}
fun hasCapability(capability: PumpCapability): Boolean = children.contains(capability)
}

View file

@ -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.
* <p>
* 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<String, PumpType> 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);
}
}

View file

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

View file

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

View file

@ -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<Carbs> =
mutableListOf<Carbs>().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
))
}
}
}

View file

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

View file

@ -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"
)
}

View file

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

View file

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

View file

@ -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()
}
}

View file

@ -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<TypeList>()

View file

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

View file

@ -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() {

View file

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

View file

@ -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)

View file

@ -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() {

View file

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

View file

@ -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 {

View file

@ -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)

View file

@ -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')"
]
}
}

View file

@ -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<List<MealLinkLoaded>> =
database.mealLinkDao.getMealLinkLoadedFromTime(timestamp)
.map { if (!ascending) it.reversed() else it }
.subscribeOn(Schedulers.io())
fun getMealLinkLoadedDataIncludingInvalidFromTime(timestamp: Long, ascending: Boolean): Single<List<MealLinkLoaded>> =
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")

View file

@ -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`)")
}
}
}

View file

@ -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<MealLink> {
@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<List<MealLinkLoaded>>
@Transaction
@Query("SELECT * FROM $TABLE_MEAL_LINKS WHERE timestamp >= :timestamp AND referenceId IS NULL ORDER BY id DESC")
fun getMealLinkLoadedIncludingInvalidFromTime(timestamp: Long): Single<List<MealLinkLoaded>>
}

View file

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

View file

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

View file

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

View file

@ -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 &&

View file

@ -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?
)

View file

@ -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<MealLink>()
val inserted = mutableListOf<MealLinkLoaded>()
}
}

View file

@ -0,0 +1,11 @@
package info.nightscout.androidaps.database.transactions
class InvalidateBolusTransaction(val id: Long) : Transaction<Unit>() {
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)
}
}

View file

@ -0,0 +1,11 @@
package info.nightscout.androidaps.database.transactions
class InvalidateCarbsTransaction(val id: Long) : Transaction<Unit>() {
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)
}
}

View file

@ -0,0 +1,42 @@
package info.nightscout.androidaps.database.transactions
class InvalidateMealLinkTransaction(val id: Long) : Transaction<Unit>() {
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)
}
}

View file

@ -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();

View file

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

View file

@ -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();

View file

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

View file

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

View file

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

View file

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

View file

@ -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("");

View file

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