IobCobCalculator refactor
This commit is contained in:
parent
639328bdc3
commit
c637b7072c
30 changed files with 222 additions and 221 deletions
|
@ -14,24 +14,24 @@ 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.ValueWithUnit
|
||||
import info.nightscout.androidaps.database.entities.TemporaryTarget
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||
import info.nightscout.androidaps.database.entities.ValueWithUnit
|
||||
import info.nightscout.androidaps.database.transactions.InsertTemporaryTargetAndCancelCurrentTransaction
|
||||
import info.nightscout.androidaps.databinding.DialogCarbsBinding
|
||||
import info.nightscout.androidaps.extensions.formatColor
|
||||
import info.nightscout.androidaps.interfaces.Constraint
|
||||
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||
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.extensions.formatColor
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
|
@ -49,7 +49,7 @@ class CarbsDialog : DialogFragmentWithDate() {
|
|||
@Inject lateinit var defaultValueHelper: DefaultValueHelper
|
||||
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var iobCobCalculatorPlugin: IobCobCalculatorPlugin
|
||||
@Inject lateinit var iobCobCalculator: IobCobCalculator
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
@Inject lateinit var carbTimer: CarbTimer
|
||||
@Inject lateinit var commandQueue: CommandQueue
|
||||
|
@ -144,7 +144,7 @@ class CarbsDialog : DialogFragmentWithDate() {
|
|||
validateInputs()
|
||||
}
|
||||
|
||||
iobCobCalculatorPlugin.actualBg()?.let { bgReading ->
|
||||
iobCobCalculator.actualBg()?.let { bgReading ->
|
||||
if (bgReading.value < 72)
|
||||
binding.hypoTt.isChecked = true
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ class CarbsDialog : DialogFragmentWithDate() {
|
|||
activitySelected -> {
|
||||
uel.log(Action.TT, Sources.CarbDialog,
|
||||
ValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.ACTIVITY),
|
||||
ValueWithUnit.fromGlucoseUnit(activityTT, units) ,
|
||||
ValueWithUnit.fromGlucoseUnit(activityTT, units),
|
||||
ValueWithUnit.Minute(activityTTDuration))
|
||||
disposable += repository.runTransactionForResult(InsertTemporaryTargetAndCancelCurrentTransaction(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
|
@ -245,7 +245,7 @@ class CarbsDialog : DialogFragmentWithDate() {
|
|||
eatingSoonSelected -> {
|
||||
uel.log(Action.TT, Sources.CarbDialog,
|
||||
ValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.EATING_SOON),
|
||||
ValueWithUnit.fromGlucoseUnit(eatingSoonTT, units) ,
|
||||
ValueWithUnit.fromGlucoseUnit(eatingSoonTT, units),
|
||||
ValueWithUnit.Minute(eatingSoonTTDuration))
|
||||
disposable += repository.runTransactionForResult(InsertTemporaryTargetAndCancelCurrentTransaction(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
|
@ -264,7 +264,7 @@ class CarbsDialog : DialogFragmentWithDate() {
|
|||
hypoSelected -> {
|
||||
uel.log(Action.TT, Sources.CarbDialog,
|
||||
ValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.HYPOGLYCEMIA),
|
||||
ValueWithUnit.fromGlucoseUnit(hypoTT, units) ,
|
||||
ValueWithUnit.fromGlucoseUnit(hypoTT, units),
|
||||
ValueWithUnit.Minute(hypoTTDuration))
|
||||
disposable += repository.runTransactionForResult(InsertTemporaryTargetAndCancelCurrentTransaction(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
|
|
|
@ -6,6 +6,9 @@ import info.nightscout.androidaps.R
|
|||
import info.nightscout.androidaps.data.IobTotal
|
||||
import info.nightscout.androidaps.data.MealData
|
||||
import info.nightscout.androidaps.data.Profile
|
||||
import info.nightscout.androidaps.extensions.convertedToAbsolute
|
||||
import info.nightscout.androidaps.extensions.getPassedDurationToTimeInMinutes
|
||||
import info.nightscout.androidaps.extensions.plannedRemainingMinutes
|
||||
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
|
@ -16,10 +19,6 @@ import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults
|
|||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||
import info.nightscout.androidaps.extensions.convertedToAbsolute
|
||||
import info.nightscout.androidaps.extensions.getPassedDurationToTimeInMinutes
|
||||
import info.nightscout.androidaps.extensions.plannedRemainingMinutes
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONException
|
||||
|
|
|
@ -107,7 +107,7 @@ open class OpenAPSAMAPlugin @Inject constructor(
|
|||
val iobArray = iobCobCalculator.calculateIobArrayInDia(profile)
|
||||
profiler.log(LTag.APS, "calculateIobArrayInDia()", startPart)
|
||||
startPart = System.currentTimeMillis()
|
||||
val mealData = iobCobCalculator.mealData
|
||||
val mealData = iobCobCalculator.getMealDataWithWaitingForCalculationFinish()
|
||||
profiler.log(LTag.APS, "getMealData()", startPart)
|
||||
val maxIob = constraintChecker.getMaxIOBAllowed().also { maxIOBAllowedConstraint ->
|
||||
inputConstraints.copyReasons(maxIOBAllowedConstraint)
|
||||
|
@ -130,7 +130,7 @@ open class OpenAPSAMAPlugin @Inject constructor(
|
|||
if (!hardLimits.checkOnlyHardLimits(pump.baseBasalRate, R.string.current_basal_value, 0.01, hardLimits.maxBasal())) return
|
||||
startPart = System.currentTimeMillis()
|
||||
if (constraintChecker.isAutosensModeEnabled().value()) {
|
||||
val autosensData = iobCobCalculator.getLastAutosensDataSynchronized("OpenAPSPlugin")
|
||||
val autosensData = iobCobCalculator.getLastAutosensDataWithWaitForCalculationFinish("OpenAPSPlugin")
|
||||
if (autosensData == null) {
|
||||
rxBus.send(EventOpenAPSUpdateResultGui(resourceHelper.gs(R.string.openaps_noasdata)))
|
||||
return
|
||||
|
|
|
@ -136,7 +136,7 @@ open class OpenAPSSMBPlugin @Inject constructor(
|
|||
if (!hardLimits.checkOnlyHardLimits(pump.baseBasalRate, R.string.current_basal_value, 0.01, hardLimits.maxBasal())) return
|
||||
startPart = System.currentTimeMillis()
|
||||
if (constraintChecker.isAutosensModeEnabled().value()) {
|
||||
val autosensData = iobCobCalculator.getLastAutosensDataSynchronized("OpenAPSPlugin")
|
||||
val autosensData = iobCobCalculator.getLastAutosensDataWithWaitForCalculationFinish("OpenAPSPlugin")
|
||||
if (autosensData == null) {
|
||||
rxBus.send(EventOpenAPSUpdateResultGui(resourceHelper.gs(R.string.openaps_noasdata)))
|
||||
return
|
||||
|
@ -169,7 +169,7 @@ open class OpenAPSSMBPlugin @Inject constructor(
|
|||
activePlugin.activePump.baseBasalRate,
|
||||
iobArray,
|
||||
glucoseStatus,
|
||||
iobCobCalculator.mealData,
|
||||
iobCobCalculator.getMealDataWithWaitingForCalculationFinish(),
|
||||
lastAutosensResult.ratio,
|
||||
isTempTarget,
|
||||
smbAllowed.value(),
|
||||
|
|
|
@ -3,11 +3,11 @@ package info.nightscout.androidaps.plugins.constraints.objectives.objectives
|
|||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
||||
import info.nightscout.androidaps.interfaces.PluginBase
|
||||
import info.nightscout.androidaps.interfaces.PluginType
|
||||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||
import javax.inject.Inject
|
||||
|
@ -19,7 +19,7 @@ class Objective0(injector: HasAndroidInjector) : Objective(injector, "config", R
|
|||
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
|
||||
@Inject lateinit var loopPlugin: LoopPlugin
|
||||
@Inject lateinit var nsClientPlugin: NSClientPlugin
|
||||
@Inject lateinit var iobCobCalculatorPlugin: IobCobCalculatorPlugin
|
||||
@Inject lateinit var iobCobCalculator: IobCobCalculator
|
||||
|
||||
init {
|
||||
tasks.add(object : Task(this, R.string.objectives_bgavailableinns) {
|
||||
|
@ -48,7 +48,7 @@ class Objective0(injector: HasAndroidInjector) : Objective(injector, "config", R
|
|||
})
|
||||
tasks.add(object : Task(this, R.string.hasbgdata) {
|
||||
override fun isCompleted(): Boolean {
|
||||
return iobCobCalculatorPlugin.lastBg() != null
|
||||
return iobCobCalculator.lastBg() != null
|
||||
}
|
||||
})
|
||||
tasks.add(object : Task(this, R.string.loopenabled) {
|
||||
|
|
|
@ -62,7 +62,7 @@ class GraphData(
|
|||
}
|
||||
|
||||
fun addBucketedData(fromTime: Long, toTime: Long) {
|
||||
val bucketedData = iobCobCalculator.bucketedData ?: return
|
||||
val bucketedData = iobCobCalculator.getBucketedDataTableCopy() ?: return
|
||||
if (bucketedData.isEmpty()) {
|
||||
aapsLogger.debug("No bucketed data.")
|
||||
return
|
||||
|
@ -70,7 +70,7 @@ class GraphData(
|
|||
val bucketedListArray: MutableList<DataPointWithLabelInterface> = ArrayList()
|
||||
for (inMemoryGlucoseValue in bucketedData) {
|
||||
if (inMemoryGlucoseValue.timestamp < fromTime || inMemoryGlucoseValue.timestamp > toTime) continue
|
||||
bucketedListArray.add(InMemoryGlucoseValueDataPoint(inMemoryGlucoseValue, qgiprofileFunction, resourceHelper))
|
||||
bucketedListArray.add(InMemoryGlucoseValueDataPoint(inMemoryGlucoseValue, profileFunction, resourceHelper))
|
||||
}
|
||||
addSeries(PointsWithLabelGraphSeries(Array(bucketedListArray.size) { i -> bucketedListArray[i] }))
|
||||
}
|
||||
|
@ -426,7 +426,7 @@ class GraphData(
|
|||
it.thickness = 3
|
||||
}
|
||||
if (showPrediction) {
|
||||
val autosensData = iobCobCalculator.getLastAutosensDataSynchronized("GraphData")
|
||||
val autosensData = iobCobCalculator.getLastAutosensDataWithWaitForCalculationFinish("GraphData")
|
||||
val lastAutosensResult = autosensData?.autosensResult ?: AutosensResult()
|
||||
val isTempTarget = repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet() is ValueWrapper.Existing
|
||||
val iobPrediction: MutableList<DataPointWithLabelInterface> = ArrayList()
|
||||
|
|
|
@ -23,6 +23,7 @@ import info.nightscout.androidaps.database.interfaces.end
|
|||
import info.nightscout.androidaps.database.transactions.CancelCurrentTemporaryTargetIfAnyTransaction
|
||||
import info.nightscout.androidaps.database.transactions.InsertTemporaryTargetAndCancelCurrentTransaction
|
||||
import info.nightscout.androidaps.db.TDD
|
||||
import info.nightscout.androidaps.extensions.valueToUnits
|
||||
import info.nightscout.androidaps.interfaces.*
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
|
@ -33,11 +34,9 @@ import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
|||
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
|
||||
import info.nightscout.androidaps.plugins.general.wear.events.EventWearConfirmAction
|
||||
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.queue.Callback
|
||||
import info.nightscout.androidaps.utils.*
|
||||
import info.nightscout.androidaps.extensions.valueToUnits
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
|
@ -71,7 +70,7 @@ class ActionStringHandler @Inject constructor(
|
|||
private val fabricPrivacy: FabricPrivacy,
|
||||
private val commandQueue: CommandQueueProvider,
|
||||
private val activePlugin: ActivePluginProvider,
|
||||
private val iobCobCalculatorPlugin: IobCobCalculatorPlugin,
|
||||
private val iobCobCalculator: IobCobCalculator,
|
||||
private val localInsightPlugin: LocalInsightPlugin,
|
||||
private val danaRPlugin: DanaRPlugin,
|
||||
private val danaRKoreanPlugin: DanaRKoreanPlugin,
|
||||
|
@ -104,7 +103,7 @@ class ActionStringHandler @Inject constructor(
|
|||
.subscribe({ handleConfirmation(it.action) }, fabricPrivacy::logException)
|
||||
}
|
||||
|
||||
fun tearDown(){
|
||||
fun tearDown() {
|
||||
disposable.clear()
|
||||
}
|
||||
|
||||
|
@ -208,12 +207,12 @@ class ActionStringHandler @Inject constructor(
|
|||
sendError("No profile found!")
|
||||
return
|
||||
}
|
||||
val bgReading = iobCobCalculatorPlugin.actualBg()
|
||||
val bgReading = iobCobCalculator.actualBg()
|
||||
if (bgReading == null) {
|
||||
sendError("No recent BG to base calculation on!")
|
||||
return
|
||||
}
|
||||
val cobInfo = iobCobCalculatorPlugin.getCobInfo(false, "Wizard wear")
|
||||
val cobInfo = iobCobCalculator.getCobInfo(false, "Wizard wear")
|
||||
if (cobInfo.displayCob == null) {
|
||||
sendError("Unknown COB! BG reading missing or recent app restart?")
|
||||
return
|
||||
|
@ -624,10 +623,10 @@ class ActionStringHandler @Inject constructor(
|
|||
}
|
||||
|
||||
private fun doECarbs(carbs: Int, time: Long, duration: Int) {
|
||||
uel.log(if (duration==0) Action.CARBS else Action.EXTENDED_CARBS, Sources.Wear,
|
||||
uel.log(if (duration == 0) Action.CARBS else Action.EXTENDED_CARBS, Sources.Wear,
|
||||
ValueWithUnit.Timestamp(time),
|
||||
ValueWithUnit.Gram(carbs),
|
||||
ValueWithUnit.Hour(duration).takeIf { duration !=0 })
|
||||
ValueWithUnit.Hour(duration).takeIf { duration != 0 })
|
||||
doBolus(0.0, carbs, time, duration)
|
||||
}
|
||||
|
||||
|
@ -640,10 +639,10 @@ class ActionStringHandler @Inject constructor(
|
|||
detailedBolusInfo.carbsDuration = T.hours(carbsDuration.toLong()).msecs()
|
||||
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) {
|
||||
val action = when {
|
||||
amount.equals(0.0) -> Action.CARBS
|
||||
carbs.equals(0) -> Action.BOLUS
|
||||
carbsDuration>0 -> Action.EXTENDED_CARBS
|
||||
else -> Action.TREATMENT
|
||||
amount.equals(0.0) -> Action.CARBS
|
||||
carbs.equals(0) -> Action.BOLUS
|
||||
carbsDuration > 0 -> Action.EXTENDED_CARBS
|
||||
else -> Action.TREATMENT
|
||||
}
|
||||
uel.log(action, Sources.Wear,
|
||||
ValueWithUnit.Insulin(amount).takeIf { amount != 0.0 },
|
||||
|
|
|
@ -78,9 +78,9 @@ open class IobCobCalculatorPlugin @Inject constructor(
|
|||
private var absIobTable = LongSparseArray<IobTotal>() // oldest at index 0, absolute insulin in the body
|
||||
private var autosensDataTable = LongSparseArray<AutosensData>() // oldest at index 0
|
||||
private var basalDataTable = LongSparseArray<BasalData>() // oldest at index 0
|
||||
override var bgReadings: List<GlucoseValue> = listOf() // newest at index 0
|
||||
internal var bgReadings: List<GlucoseValue> = listOf() // newest at index 0
|
||||
|
||||
@Volatile override var bucketedData: MutableList<InMemoryGlucoseValue>? = null
|
||||
internal var bucketedData: MutableList<InMemoryGlucoseValue>? = null
|
||||
|
||||
// we need to make sure that bucketed_data will always have the same timestamp for correct use of cached values
|
||||
// once referenceTime != null all bucketed data should be (x * 5min) from referenceTime
|
||||
|
@ -135,9 +135,9 @@ open class IobCobCalculatorPlugin @Inject constructor(
|
|||
super.onStop()
|
||||
}
|
||||
|
||||
override fun getAutosensDataTable(): LongSparseArray<AutosensData> {
|
||||
return autosensDataTable
|
||||
}
|
||||
override fun getBgReadingsDataTableCopy(): List<GlucoseValue> = bgReadings.toList()
|
||||
override fun getBucketedDataTableCopy(): MutableList<InMemoryGlucoseValue>? = bucketedData?.toMutableList()
|
||||
override fun getAutosensDataTable(): LongSparseArray<AutosensData> = autosensDataTable
|
||||
|
||||
private fun adjustToReferenceTime(someTime: Long): Long {
|
||||
if (referenceTime == -1L) {
|
||||
|
@ -503,7 +503,7 @@ open class IobCobCalculatorPlugin @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun getLastAutosensDataSynchronized(reason: String): AutosensData? {
|
||||
override fun getLastAutosensDataWithWaitForCalculationFinish(reason: String): AutosensData? {
|
||||
if (thread?.isAlive == true) {
|
||||
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA is waiting for calculation thread: $reason")
|
||||
try {
|
||||
|
@ -515,8 +515,10 @@ open class IobCobCalculatorPlugin @Inject constructor(
|
|||
synchronized(dataLock) { return getLastAutosensData(reason) }
|
||||
}
|
||||
|
||||
override fun getCobInfo(_synchronized: Boolean, reason: String): CobInfo {
|
||||
val autosensData = if (_synchronized) getLastAutosensDataSynchronized(reason) else getLastAutosensData(reason)
|
||||
override fun getCobInfo(waitForCalculationFinish: Boolean, reason: String): CobInfo {
|
||||
val autosensData =
|
||||
if (waitForCalculationFinish) getLastAutosensDataWithWaitForCalculationFinish(reason)
|
||||
else getLastAutosensData(reason)
|
||||
var displayCob: Double? = null
|
||||
var futureCarbs = 0.0
|
||||
val now = dateUtil.now()
|
||||
|
@ -576,39 +578,38 @@ open class IobCobCalculatorPlugin @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun lastDataTime(): String {
|
||||
return if (autosensDataTable.size() > 0) dateUtil.dateAndTimeAndSecondsString(autosensDataTable.valueAt(autosensDataTable.size() - 1).time) else "autosensDataTable empty"
|
||||
}
|
||||
override fun lastDataTime(): String =
|
||||
if (autosensDataTable.size() > 0) dateUtil.dateAndTimeAndSecondsString(autosensDataTable.valueAt(autosensDataTable.size() - 1).time)
|
||||
else "autosensDataTable empty"
|
||||
|
||||
override val mealData: MealData
|
||||
get() {
|
||||
val result = MealData()
|
||||
val now = System.currentTimeMillis()
|
||||
val maxAbsorptionHours: Double = if (sensitivityAAPSPlugin.isEnabled() || sensitivityWeightedAveragePlugin.isEnabled()) {
|
||||
sp.getDouble(R.string.key_absorption_maxtime, Constants.DEFAULT_MAX_ABSORPTION_TIME)
|
||||
} else {
|
||||
sp.getDouble(R.string.key_absorption_cutoff, Constants.DEFAULT_MAX_ABSORPTION_TIME)
|
||||
}
|
||||
val absorptionTimeAgo = now - (maxAbsorptionHours * T.hours(1).msecs()).toLong()
|
||||
repository.getCarbsDataFromTimeToTimeExpanded(absorptionTimeAgo + 1, now, true)
|
||||
.blockingGet()
|
||||
.forEach {
|
||||
if (it.amount > 0) {
|
||||
result.carbs += it.amount
|
||||
if (it.timestamp > result.lastCarbTime) result.lastCarbTime = it.timestamp
|
||||
}
|
||||
}
|
||||
val autosensData = getLastAutosensDataSynchronized("getMealData()")
|
||||
if (autosensData != null) {
|
||||
result.mealCOB = autosensData.cob
|
||||
result.slopeFromMinDeviation = autosensData.slopeFromMinDeviation
|
||||
result.slopeFromMaxDeviation = autosensData.slopeFromMaxDeviation
|
||||
result.usedMinCarbsImpact = autosensData.usedMinCarbsImpact
|
||||
}
|
||||
val lastBolus = repository.getLastBolusRecordWrapped().blockingGet()
|
||||
result.lastBolusTime = if (lastBolus is ValueWrapper.Existing) lastBolus.value.timestamp else 0L
|
||||
return result
|
||||
override fun getMealDataWithWaitingForCalculationFinish(): MealData {
|
||||
val result = MealData()
|
||||
val now = System.currentTimeMillis()
|
||||
val maxAbsorptionHours: Double = if (sensitivityAAPSPlugin.isEnabled() || sensitivityWeightedAveragePlugin.isEnabled()) {
|
||||
sp.getDouble(R.string.key_absorption_maxtime, Constants.DEFAULT_MAX_ABSORPTION_TIME)
|
||||
} else {
|
||||
sp.getDouble(R.string.key_absorption_cutoff, Constants.DEFAULT_MAX_ABSORPTION_TIME)
|
||||
}
|
||||
val absorptionTimeAgo = now - (maxAbsorptionHours * T.hours(1).msecs()).toLong()
|
||||
repository.getCarbsDataFromTimeToTimeExpanded(absorptionTimeAgo + 1, now, true)
|
||||
.blockingGet()
|
||||
.forEach {
|
||||
if (it.amount > 0) {
|
||||
result.carbs += it.amount
|
||||
if (it.timestamp > result.lastCarbTime) result.lastCarbTime = it.timestamp
|
||||
}
|
||||
}
|
||||
val autosensData = getLastAutosensDataWithWaitForCalculationFinish("getMealData()")
|
||||
if (autosensData != null) {
|
||||
result.mealCOB = autosensData.cob
|
||||
result.slopeFromMinDeviation = autosensData.slopeFromMinDeviation
|
||||
result.slopeFromMaxDeviation = autosensData.slopeFromMaxDeviation
|
||||
result.usedMinCarbsImpact = autosensData.usedMinCarbsImpact
|
||||
}
|
||||
val lastBolus = repository.getLastBolusRecordWrapped().blockingGet()
|
||||
result.lastBolusTime = if (lastBolus is ValueWrapper.Existing) lastBolus.value.timestamp else 0L
|
||||
return result
|
||||
}
|
||||
|
||||
override fun calculateIobArrayInDia(profile: Profile): Array<IobTotal> {
|
||||
// predict IOB out to DIA plus 30m
|
||||
|
@ -656,7 +657,7 @@ open class IobCobCalculatorPlugin @Inject constructor(
|
|||
if (thread?.state != Thread.State.TERMINATED) {
|
||||
stopCalculationTrigger = true
|
||||
aapsLogger.debug(LTag.AUTOSENS, "Stopping calculation thread: $from")
|
||||
while (thread?.state != Thread.State.TERMINATED) {
|
||||
while (thread != null && thread?.state != Thread.State.TERMINATED) {
|
||||
SystemClock.sleep(100)
|
||||
}
|
||||
aapsLogger.debug(LTag.AUTOSENS, "Calculation thread stopped: $from")
|
||||
|
|
|
@ -81,7 +81,7 @@ class IobCobOref1Thread internal constructor(
|
|||
iobCobCalculatorPlugin.loadBgData(end)
|
||||
iobCobCalculatorPlugin.createBucketedData()
|
||||
}
|
||||
val bucketedData = iobCobCalculatorPlugin.bucketedData
|
||||
val bucketedData = iobCobCalculatorPlugin.getBucketedDataTableCopy()
|
||||
val autosensDataTable = iobCobCalculatorPlugin.getAutosensDataTable()
|
||||
if (bucketedData == null || bucketedData.size < 3) {
|
||||
aapsLogger.debug(LTag.AUTOSENS, "Aborting calculation thread (No bucketed data available): $from")
|
||||
|
@ -156,7 +156,7 @@ class IobCobOref1Thread internal constructor(
|
|||
if (ad == null) {
|
||||
aapsLogger.debug(LTag.AUTOSENS, autosensDataTable.toString())
|
||||
aapsLogger.debug(LTag.AUTOSENS, bucketedData.toString())
|
||||
aapsLogger.debug(LTag.AUTOSENS, iobCobCalculatorPlugin.bgReadings.toString())
|
||||
//aapsLogger.debug(LTag.AUTOSENS, iobCobCalculatorPlugin.getBgReadingsDataTable().toString())
|
||||
val notification = Notification(Notification.SEND_LOGFILES, resourceHelper.gs(R.string.sendlogfiles), Notification.LOW)
|
||||
rxBus.send(EventNewNotification(notification))
|
||||
sp.putBoolean("log_AUTOSENS", true)
|
||||
|
@ -179,7 +179,7 @@ class IobCobOref1Thread internal constructor(
|
|||
fabricPrivacy.logException(e)
|
||||
aapsLogger.debug(autosensDataTable.toString())
|
||||
aapsLogger.debug(bucketedData.toString())
|
||||
aapsLogger.debug(iobCobCalculatorPlugin.bgReadings.toString())
|
||||
//aapsLogger.debug(iobCobCalculatorPlugin.getBgReadingsDataTable().toString())
|
||||
val notification = Notification(Notification.SEND_LOGFILES, resourceHelper.gs(R.string.sendlogfiles), Notification.LOW)
|
||||
rxBus.send(EventNewNotification(notification))
|
||||
sp.putBoolean("log_AUTOSENS", true)
|
||||
|
|
|
@ -79,7 +79,7 @@ class IobCobThread @Inject internal constructor(
|
|||
iobCobCalculatorPlugin.loadBgData(end)
|
||||
iobCobCalculatorPlugin.createBucketedData()
|
||||
}
|
||||
val bucketedData = iobCobCalculatorPlugin.bucketedData
|
||||
val bucketedData = iobCobCalculatorPlugin.getBucketedDataTableCopy()
|
||||
val autosensDataTable = iobCobCalculatorPlugin.getAutosensDataTable()
|
||||
if (bucketedData == null || bucketedData.size < 3) {
|
||||
aapsLogger.debug(LTag.AUTOSENS, "Aborting calculation thread (No bucketed data available): $from")
|
||||
|
@ -152,7 +152,7 @@ class IobCobThread @Inject internal constructor(
|
|||
if (ad == null) {
|
||||
aapsLogger.debug(LTag.AUTOSENS, autosensDataTable.toString())
|
||||
aapsLogger.debug(LTag.AUTOSENS, bucketedData.toString())
|
||||
aapsLogger.debug(LTag.AUTOSENS, iobCobCalculatorPlugin.bgReadings.toString())
|
||||
//aapsLogger.debug(LTag.AUTOSENS, iobCobCalculatorPlugin.getBgReadingsDataTable().toString())
|
||||
val notification = Notification(Notification.SEND_LOGFILES, resourceHelper.gs(R.string.sendlogfiles), Notification.LOW)
|
||||
rxBus.send(EventNewNotification(notification))
|
||||
sp.putBoolean("log_AUTOSENS", true)
|
||||
|
@ -175,7 +175,7 @@ class IobCobThread @Inject internal constructor(
|
|||
fabricPrivacy.logException(e)
|
||||
aapsLogger.debug(autosensDataTable.toString())
|
||||
aapsLogger.debug(bucketedData.toString())
|
||||
aapsLogger.debug(iobCobCalculatorPlugin.bgReadings.toString())
|
||||
//aapsLogger.debug(iobCobCalculatorPlugin.getBgReadingsDataTable().toString())
|
||||
val notification = Notification(Notification.SEND_LOGFILES, resourceHelper.gs(R.string.sendlogfiles), Notification.LOW)
|
||||
rxBus.send(EventNewNotification(notification))
|
||||
sp.putBoolean("log_AUTOSENS", true)
|
||||
|
|
|
@ -31,10 +31,10 @@ import kotlin.math.roundToInt
|
|||
|
||||
@Singleton
|
||||
open class SensitivityOref1Plugin @Inject constructor(
|
||||
injector: HasAndroidInjector?,
|
||||
aapsLogger: AAPSLogger?,
|
||||
resourceHelper: ResourceHelper?,
|
||||
sp: SP?,
|
||||
injector: HasAndroidInjector,
|
||||
aapsLogger: AAPSLogger,
|
||||
resourceHelper: ResourceHelper,
|
||||
sp: SP,
|
||||
private val profileFunction: ProfileFunction,
|
||||
private val dateUtil: DateUtil,
|
||||
private val databaseHelper: DatabaseHelperInterface,
|
||||
|
@ -48,7 +48,7 @@ open class SensitivityOref1Plugin @Inject constructor(
|
|||
.preferencesId(R.xml.pref_absorption_oref1)
|
||||
.description(R.string.description_sensitivity_oref1)
|
||||
.setDefault(),
|
||||
injector!!, aapsLogger!!, resourceHelper!!, sp!!
|
||||
injector, aapsLogger, resourceHelper, sp
|
||||
) {
|
||||
|
||||
override fun detectSensitivity(plugin: IobCobCalculator, fromTime: Long, toTime: Long): AutosensResult {
|
||||
|
|
|
@ -17,21 +17,21 @@ import info.nightscout.androidaps.BuildConfig
|
|||
import info.nightscout.androidaps.Config
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.events.EventProfileNeedsUpdate
|
||||
import info.nightscout.androidaps.extensions.buildDeviceStatus
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||
import info.nightscout.androidaps.interfaces.CommandQueueProvider
|
||||
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.configBuilder.RunningConfiguration
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||
import info.nightscout.androidaps.queue.commands.Command
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.LocalAlertUtils
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import info.nightscout.androidaps.extensions.buildDeviceStatus
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.abs
|
||||
|
||||
|
@ -61,7 +61,7 @@ class KeepAliveReceiver : DaggerBroadcastReceiver() {
|
|||
@Inject lateinit var localAlertUtils: LocalAlertUtils
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var config: Config
|
||||
@Inject lateinit var iobCobCalculatorPlugin: IobCobCalculatorPlugin
|
||||
@Inject lateinit var iobCobCalculator: IobCobCalculator
|
||||
@Inject lateinit var loopPlugin: LoopPlugin
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var activePlugin: ActivePluginProvider
|
||||
|
@ -102,12 +102,12 @@ class KeepAliveReceiver : DaggerBroadcastReceiver() {
|
|||
var shouldUploadStatus = false
|
||||
if (config.NSCLIENT) return
|
||||
if (config.PUMPCONTROL) shouldUploadStatus = true
|
||||
else if (!loopPlugin.isEnabled() || iobCobCalculatorPlugin.actualBg() == null)
|
||||
else if (!loopPlugin.isEnabled() || iobCobCalculator.actualBg() == null)
|
||||
shouldUploadStatus = true
|
||||
else if (dateUtil.isOlderThan(activePlugin.activeAPS.lastAPSRun, 5)) shouldUploadStatus = true
|
||||
if (dateUtil.isOlderThan(lastIobUpload, IOB_UPDATE_FREQUENCY_IN_MINUTES) && shouldUploadStatus) {
|
||||
lastIobUpload = dateUtil.now()
|
||||
buildDeviceStatus(dateUtil, loopPlugin, iobCobCalculatorPlugin, profileFunction,
|
||||
buildDeviceStatus(dateUtil, loopPlugin, iobCobCalculator, profileFunction,
|
||||
activePlugin.activePump, receiverStatusStore, runningConfiguration,
|
||||
BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION)?.also {
|
||||
repository.insert(it)
|
||||
|
|
|
@ -6,6 +6,7 @@ import info.nightscout.androidaps.R
|
|||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.transactions.InsertTherapyEventAnnouncementTransaction
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
|
@ -14,7 +15,6 @@ import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNo
|
|||
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
|
||||
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
|
@ -34,7 +34,7 @@ class LocalAlertUtils @Inject constructor(
|
|||
private val resourceHelper: ResourceHelper,
|
||||
private val activePlugin: ActivePluginProvider,
|
||||
private val profileFunction: ProfileFunction,
|
||||
private val iobCobCalculatorPlugin: IobCobCalculatorPlugin,
|
||||
private val iobCobCalculator: IobCobCalculator,
|
||||
private val smsCommunicatorPlugin: SmsCommunicatorPlugin,
|
||||
private val config: Config,
|
||||
private val repository: AppRepository,
|
||||
|
@ -110,7 +110,7 @@ class LocalAlertUtils @Inject constructor(
|
|||
}
|
||||
|
||||
fun checkStaleBGAlert() {
|
||||
val bgReading = iobCobCalculatorPlugin.lastBg()
|
||||
val bgReading = iobCobCalculator.lastBg()
|
||||
if (sp.getBoolean(R.string.key_enable_missed_bg_readings_alert, false)
|
||||
&& bgReading != null && bgReading.timestamp + missedReadingsThreshold() < System.currentTimeMillis() && sp.getLong("nextMissedReadingsAlarm", 0L) < System.currentTimeMillis()) {
|
||||
val n = Notification(Notification.BG_READINGS_MISSED, resourceHelper.gs(R.string.missed_bg_readings), Notification.URGENT)
|
||||
|
|
|
@ -22,7 +22,6 @@ import info.nightscout.androidaps.plugins.constraints.safety.SafetyPlugin
|
|||
import info.nightscout.androidaps.plugins.general.maintenance.LoggerUtils
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.common.bolusInfo.DetailedBolusInfoStorage
|
||||
import info.nightscout.androidaps.plugins.pump.common.bolusInfo.TemporaryBasalStorage
|
||||
|
@ -54,7 +53,7 @@ import java.util.*
|
|||
ConfigBuilderPlugin::class, ConstraintChecker::class, SP::class, Context::class,
|
||||
OpenAPSAMAPlugin::class, OpenAPSSMBPlugin::class, TreatmentsPlugin::class, TreatmentService::class,
|
||||
VirtualPumpPlugin::class, DetailedBolusInfoStorage::class, TemporaryBasalStorage::class, GlimpPlugin::class, Profiler::class,
|
||||
UserEntryLogger::class, IobCobCalculatorPlugin::class, LoggerUtils::class, AppRepository::class)
|
||||
UserEntryLogger::class, LoggerUtils::class, AppRepository::class)
|
||||
class ConstraintsCheckerTest : TestBaseWithProfile() {
|
||||
|
||||
@Mock lateinit var activePlugin: ActivePluginProvider
|
||||
|
|
|
@ -14,7 +14,11 @@ import info.nightscout.androidaps.data.PumpEnactResult
|
|||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||
import info.nightscout.androidaps.database.transactions.InsertTemporaryTargetAndCancelCurrentTransaction
|
||||
import info.nightscout.androidaps.interfaces.*
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||
import info.nightscout.androidaps.interfaces.CommandQueueProvider
|
||||
import info.nightscout.androidaps.interfaces.Constraint
|
||||
import info.nightscout.androidaps.interfaces.PluginType
|
||||
import info.nightscout.androidaps.interfaces.PumpDescription
|
||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||
|
@ -22,7 +26,6 @@ import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePas
|
|||
import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
|
||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
|
||||
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
|
||||
|
@ -55,7 +58,7 @@ import java.util.*
|
|||
@PrepareForTest(
|
||||
ConstraintChecker::class, FabricPrivacy::class, VirtualPumpPlugin::class, XdripCalibrations::class,
|
||||
SmsManager::class, CommandQueue::class, LocalProfilePlugin::class, DateUtil::class,
|
||||
IobCobCalculatorPlugin::class, OneTimePassword::class, UserEntryLogger::class, LoopPlugin::class,
|
||||
OneTimePassword::class, UserEntryLogger::class, LoopPlugin::class,
|
||||
AppRepository::class, DateUtil::class)
|
||||
class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
||||
|
||||
|
@ -96,8 +99,6 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
|||
val bgList: MutableList<GlucoseValue> = ArrayList()
|
||||
bgList.add(reading)
|
||||
|
||||
`when`(iobCobCalculator.dataLock).thenReturn(Any())
|
||||
`when`(iobCobCalculator.bgReadings).thenReturn(bgList)
|
||||
`when`(iobCobCalculator.getCobInfo(false, "SMS COB")).thenReturn(CobInfo(10.0, 2.0))
|
||||
`when`(iobCobCalculator.lastBg()).thenReturn(reading)
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package info.nightscout.androidaps.plugins.iob.iobCobCalculator
|
||||
|
||||
import android.content.Context
|
||||
import android.os.PowerManager
|
||||
import dagger.android.AndroidInjector
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.TestBase
|
||||
|
@ -22,6 +23,7 @@ import org.junit.Before
|
|||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.`when`
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest
|
||||
import org.powermock.modules.junit4.PowerMockRunner
|
||||
import java.util.*
|
||||
|
@ -41,18 +43,25 @@ class IobCobCalculatorPluginTest : TestBase() {
|
|||
@Mock lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Mock lateinit var repository: AppRepository
|
||||
@Mock lateinit var context: Context
|
||||
@Mock lateinit var powerManager: PowerManager
|
||||
|
||||
lateinit var dateUtil: DateUtil
|
||||
lateinit var iobCobCalculatorPlugin: IobCobCalculatorPlugin
|
||||
private lateinit var iobCobCalculatorPlugin: IobCobCalculatorPlugin
|
||||
|
||||
val injector = HasAndroidInjector {
|
||||
AndroidInjector {
|
||||
if (it is IobCobThread) {
|
||||
it.context = context
|
||||
it.resourceHelper = resourceHelper
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
fun mock() {
|
||||
dateUtil = DateUtil(context)
|
||||
`when`(context.applicationContext).thenReturn(context)
|
||||
`when`(context.getSystemService(anyObject())).thenReturn(powerManager)
|
||||
iobCobCalculatorPlugin = IobCobCalculatorPlugin(injector, aapsLogger, aapsSchedulers, rxBus, sp, resourceHelper, profileFunction, activePlugin, sensitivityOref1Plugin, sensitivityAAPSPlugin, sensitivityWeightedAveragePlugin, fabricPrivacy, dateUtil, repository)
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ 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.iob.iobCobCalculator.GlucoseStatusProvider
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
|
@ -28,7 +27,7 @@ import org.powermock.core.classloader.annotations.PrepareForTest
|
|||
import org.powermock.modules.junit4.PowerMockRunner
|
||||
|
||||
@RunWith(PowerMockRunner::class)
|
||||
@PrepareForTest(ConstraintChecker::class, VirtualPumpPlugin::class, IobCobCalculatorPlugin::class, DateUtil::class)
|
||||
@PrepareForTest(ConstraintChecker::class, VirtualPumpPlugin::class, DateUtil::class)
|
||||
class BolusWizardTest : TestBase() {
|
||||
|
||||
private val pumpBolusStep = 0.1
|
||||
|
@ -71,7 +70,6 @@ class BolusWizardTest : TestBase() {
|
|||
`when`(profile.ic).thenReturn(insulinToCarbRatio)
|
||||
|
||||
`when`(profileFunction.getUnits()).thenReturn(Constants.MGDL)
|
||||
`when`(iobCobCalculator.dataLock).thenReturn(Any())
|
||||
`when`(activePlugin.activeTreatments).thenReturn(treatmentsPlugin)
|
||||
`when`(iobCobCalculator.calculateIobFromBolus()).thenReturn(IobTotal(System.currentTimeMillis()))
|
||||
`when`(iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended()).thenReturn(IobTotal(System.currentTimeMillis()))
|
||||
|
|
|
@ -38,7 +38,7 @@ abstract class Trigger(val injector: HasAndroidInjector) {
|
|||
@Inject lateinit var locationDataContainer: LastLocationDataContainer
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var activePlugin: ActivePluginProvider
|
||||
@Inject lateinit var iobCobCalculatorPlugin: IobCobCalculator
|
||||
@Inject lateinit var iobCobCalculator: IobCobCalculator
|
||||
@Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ class TriggerAutosensValue(injector: HasAndroidInjector) : Trigger(injector) {
|
|||
}
|
||||
|
||||
override fun shouldRun(): Boolean {
|
||||
val autosensData = iobCobCalculatorPlugin.getLastAutosensData("Automation trigger")
|
||||
val autosensData = iobCobCalculator.getLastAutosensData("Automation trigger")
|
||||
?: return if (comparator.value == Comparator.Compare.IS_NOT_AVAILABLE) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||
true
|
||||
|
|
|
@ -38,7 +38,7 @@ class TriggerCOB(injector: HasAndroidInjector) : Trigger(injector) {
|
|||
}
|
||||
|
||||
override fun shouldRun(): Boolean {
|
||||
val cobInfo = iobCobCalculatorPlugin.getCobInfo(false, "AutomationTriggerCOB")
|
||||
val cobInfo = iobCobCalculator.getCobInfo(false, "AutomationTriggerCOB")
|
||||
if (cobInfo.displayCob == null) {
|
||||
return if (comparator.value === Comparator.Compare.IS_NOT_AVAILABLE) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||
|
|
|
@ -34,7 +34,7 @@ class TriggerIob(injector: HasAndroidInjector) : Trigger(injector) {
|
|||
|
||||
override fun shouldRun(): Boolean {
|
||||
val profile = profileFunction.getProfile() ?: return false
|
||||
val iob = iobCobCalculatorPlugin.calculateFromTreatmentsAndTempsSynchronized(dateUtil.now(), profile)
|
||||
val iob = iobCobCalculator.calculateFromTreatmentsAndTempsSynchronized(dateUtil.now(), profile)
|
||||
if (comparator.value.check(iob.iob, insulin.value)) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||
return true
|
||||
|
|
|
@ -25,7 +25,7 @@ class TriggerAutosensValueTest : TriggerTestBase() {
|
|||
@Test fun shouldRunTest() {
|
||||
`when`(sp.getDouble(Mockito.eq(R.string.key_openapsama_autosens_max), ArgumentMatchers.anyDouble())).thenReturn(1.2)
|
||||
`when`(sp.getDouble(Mockito.eq(R.string.key_openapsama_autosens_min), ArgumentMatchers.anyDouble())).thenReturn(0.7)
|
||||
`when`(iobCobCalculatorPlugin.getLastAutosensData("Automation trigger")).thenReturn(generateAutosensData())
|
||||
`when`(iobCobCalculator.getLastAutosensData("Automation trigger")).thenReturn(generateAutosensData())
|
||||
var t = TriggerAutosensValue(injector)
|
||||
t.autosens.value = 110.0
|
||||
t.comparator.value = Comparator.Compare.IS_EQUAL
|
||||
|
@ -65,14 +65,14 @@ class TriggerAutosensValueTest : TriggerTestBase() {
|
|||
t.autosens.value = 390.0
|
||||
t.comparator.value = Comparator.Compare.IS_EQUAL_OR_LESSER
|
||||
Assert.assertTrue(t.shouldRun())
|
||||
PowerMockito.`when`(iobCobCalculatorPlugin.getLastAutosensData("Automation trigger")).thenReturn(AutosensData(injector))
|
||||
PowerMockito.`when`(iobCobCalculator.getLastAutosensData("Automation trigger")).thenReturn(AutosensData(injector))
|
||||
t = TriggerAutosensValue(injector)
|
||||
t.autosens.value = 80.0
|
||||
t.comparator.value = Comparator.Compare.IS_EQUAL_OR_LESSER
|
||||
Assert.assertFalse(t.shouldRun())
|
||||
|
||||
// Test autosensData == null and Comparator == IS_NOT_AVAILABLE
|
||||
PowerMockito.`when`(iobCobCalculatorPlugin.getLastAutosensData("Automation trigger")).thenReturn(null)
|
||||
PowerMockito.`when`(iobCobCalculator.getLastAutosensData("Automation trigger")).thenReturn(null)
|
||||
t = TriggerAutosensValue(injector)
|
||||
t.comparator.value = Comparator.Compare.IS_NOT_AVAILABLE
|
||||
Assert.assertTrue(t.shouldRun())
|
||||
|
|
|
@ -26,13 +26,12 @@ class TriggerBgTest : TriggerTestBase() {
|
|||
@Before
|
||||
fun prepare() {
|
||||
`when`(profileFunction.getUnits()).thenReturn(Constants.MGDL)
|
||||
`when`(iobCobCalculatorPlugin.dataLock).thenReturn(Any())
|
||||
`when`(dateUtil.now()).thenReturn(now)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldRunTest() {
|
||||
`when`(iobCobCalculatorPlugin.bgReadings).thenReturn(generateOneCurrentRecordBgData())
|
||||
`when`(iobCobCalculator.getBgReadingsDataTableCopy()).thenReturn(generateOneCurrentRecordBgData())
|
||||
var t: TriggerBg = TriggerBg(injector).setUnits(Constants.MMOL).setValue(4.1).comparator(Comparator.Compare.IS_EQUAL)
|
||||
Assert.assertFalse(t.shouldRun())
|
||||
t = TriggerBg(injector).setUnits(Constants.MGDL).setValue(214.0).comparator(Comparator.Compare.IS_EQUAL)
|
||||
|
@ -51,7 +50,7 @@ class TriggerBgTest : TriggerTestBase() {
|
|||
Assert.assertTrue(t.shouldRun())
|
||||
t = TriggerBg(injector).setUnits(Constants.MGDL).setValue(213.0).comparator(Comparator.Compare.IS_EQUAL_OR_LESSER)
|
||||
Assert.assertFalse(t.shouldRun())
|
||||
`when`(iobCobCalculatorPlugin.bgReadings).thenReturn(ArrayList())
|
||||
`when`(iobCobCalculator.getBgReadingsDataTableCopy()).thenReturn(ArrayList())
|
||||
t = TriggerBg(injector).setUnits(Constants.MGDL).setValue(213.0).comparator(Comparator.Compare.IS_EQUAL_OR_LESSER)
|
||||
Assert.assertFalse(t.shouldRun())
|
||||
t = TriggerBg(injector).comparator(Comparator.Compare.IS_NOT_AVAILABLE)
|
||||
|
|
|
@ -28,7 +28,7 @@ class TriggerCOBTest : TriggerTestBase() {
|
|||
|
||||
@Test fun shouldRunTest() {
|
||||
// COB value is 6
|
||||
PowerMockito.`when`(iobCobCalculatorPlugin.getCobInfo(false, "AutomationTriggerCOB")).thenReturn(CobInfo(6.0, 2.0))
|
||||
PowerMockito.`when`(iobCobCalculator.getCobInfo(false, "AutomationTriggerCOB")).thenReturn(CobInfo(6.0, 2.0))
|
||||
var t: TriggerCOB = TriggerCOB(injector).setValue(1.0).comparator(Comparator.Compare.IS_EQUAL)
|
||||
Assert.assertFalse(t.shouldRun())
|
||||
t = TriggerCOB(injector).setValue(6.0).comparator(Comparator.Compare.IS_EQUAL)
|
||||
|
|
|
@ -20,7 +20,7 @@ import org.powermock.modules.junit4.PowerMockRunner
|
|||
import java.util.*
|
||||
|
||||
@RunWith(PowerMockRunner::class)
|
||||
@PrepareForTest(DateUtil::class, ProfileFunction::class)
|
||||
@PrepareForTest(DateUtil::class, ProfileFunction::class)
|
||||
class TriggerDeltaTest : TriggerTestBase() {
|
||||
|
||||
var now = 1514766900000L
|
||||
|
@ -28,12 +28,11 @@ class TriggerDeltaTest : TriggerTestBase() {
|
|||
@Before
|
||||
fun mock() {
|
||||
PowerMockito.`when`(dateUtil.now()).thenReturn(now)
|
||||
`when`(iobCobCalculatorPlugin.dataLock).thenReturn(Any())
|
||||
`when`(profileFunction.getUnits()).thenReturn(Constants.MGDL)
|
||||
}
|
||||
|
||||
@Test fun shouldRunTest() {
|
||||
`when`(iobCobCalculatorPlugin.bgReadings).thenReturn(generateValidBgData())
|
||||
`when`(iobCobCalculator.getBgReadingsDataTableCopy()).thenReturn(generateValidBgData())
|
||||
var t = TriggerDelta(injector).units(Constants.MGDL).setValue(73.0, DeltaType.LONG_AVERAGE).comparator(Comparator.Compare.IS_EQUAL)
|
||||
Assert.assertFalse(t.shouldRun())
|
||||
Assert.assertEquals(DeltaType.LONG_AVERAGE, t.delta.deltaType)
|
||||
|
@ -55,7 +54,7 @@ class TriggerDeltaTest : TriggerTestBase() {
|
|||
Assert.assertFalse(t.shouldRun())
|
||||
t = TriggerDelta(injector).units(Constants.MGDL).setValue(-0.2, DeltaType.LONG_AVERAGE).comparator(Comparator.Compare.IS_EQUAL_OR_LESSER)
|
||||
Assert.assertTrue(t.shouldRun())
|
||||
`when`(iobCobCalculatorPlugin.bgReadings).thenReturn(ArrayList())
|
||||
`when`(iobCobCalculator.getBgReadingsDataTableCopy()).thenReturn(ArrayList())
|
||||
t = TriggerDelta(injector).units(Constants.MGDL).setValue(213.0, DeltaType.DELTA).comparator(Comparator.Compare.IS_EQUAL_OR_LESSER)
|
||||
Assert.assertFalse(t.shouldRun())
|
||||
t = TriggerDelta(injector).comparator(Comparator.Compare.IS_NOT_AVAILABLE)
|
||||
|
|
|
@ -27,7 +27,7 @@ class TriggerIobTest : TriggerTestBase() {
|
|||
}
|
||||
|
||||
@Test fun shouldRunTest() {
|
||||
`when`(iobCobCalculatorPlugin.calculateFromTreatmentsAndTempsSynchronized(ArgumentMatchers.anyLong(), anyObject())).thenReturn(generateIobRecordData())
|
||||
`when`(iobCobCalculator.calculateFromTreatmentsAndTempsSynchronized(ArgumentMatchers.anyLong(), anyObject())).thenReturn(generateIobRecordData())
|
||||
var t: TriggerIob = TriggerIob(injector).setValue(1.1).comparator(Comparator.Compare.IS_EQUAL)
|
||||
Assert.assertFalse(t.shouldRun())
|
||||
t = TriggerIob(injector).setValue(1.0).comparator(Comparator.Compare.IS_EQUAL)
|
||||
|
|
|
@ -5,7 +5,6 @@ import dagger.android.AndroidInjector
|
|||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.TestBaseWithProfile
|
||||
import info.nightscout.androidaps.TestPumpPlugin
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
||||
import info.nightscout.androidaps.interfaces.PluginDescription
|
||||
|
@ -14,7 +13,6 @@ import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
|
|||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
|
||||
import info.nightscout.androidaps.receivers.ReceiverStatusStore
|
||||
import info.nightscout.androidaps.services.LastLocationDataContainer
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import org.junit.Before
|
||||
import org.mockito.Mock
|
||||
|
@ -27,7 +25,7 @@ open class TriggerTestBase : TestBaseWithProfile() {
|
|||
@Mock lateinit var sp: SP
|
||||
@Mock lateinit var locationDataContainer: LastLocationDataContainer
|
||||
@Mock lateinit var activePlugin: ActivePluginProvider
|
||||
@Mock lateinit var iobCobCalculatorPlugin: IobCobCalculator
|
||||
@Mock lateinit var iobCobCalculator: IobCobCalculator
|
||||
@Mock lateinit var context: Context
|
||||
@Mock lateinit var automationPlugin: AutomationPlugin
|
||||
|
||||
|
@ -53,8 +51,8 @@ open class TriggerTestBase : TestBaseWithProfile() {
|
|||
it.locationDataContainer = locationDataContainer
|
||||
it.repository = repository
|
||||
it.activePlugin = activePlugin
|
||||
it.iobCobCalculatorPlugin = iobCobCalculatorPlugin
|
||||
it.glucoseStatusProvider = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil)
|
||||
it.iobCobCalculator = iobCobCalculator
|
||||
it.glucoseStatusProvider = GlucoseStatusProvider(aapsLogger, iobCobCalculator, dateUtil)
|
||||
it.dateUtil = dateUtil
|
||||
}
|
||||
if (it is TriggerBg) {
|
||||
|
|
|
@ -17,25 +17,28 @@ import org.json.JSONArray
|
|||
interface IobCobCalculator {
|
||||
|
||||
val dataLock: Any
|
||||
var bgReadings: List<GlucoseValue>
|
||||
var bucketedData: MutableList<InMemoryGlucoseValue>?
|
||||
|
||||
val mealData: MealData
|
||||
fun getBgReadingsDataTableCopy(): List<GlucoseValue>
|
||||
fun getBucketedDataTableCopy(): MutableList<InMemoryGlucoseValue>?
|
||||
fun getAutosensDataTable(): LongSparseArray<AutosensData>
|
||||
fun calculateIobArrayInDia(profile: Profile): Array<IobTotal>
|
||||
|
||||
|
||||
fun getMealDataWithWaitingForCalculationFinish(): MealData
|
||||
fun lastDataTime(): String
|
||||
fun getAutosensData(fromTime: Long): AutosensData?
|
||||
fun getLastAutosensData(reason: String): AutosensData?
|
||||
fun getLastAutosensDataSynchronized(reason: String): AutosensData?
|
||||
fun getLastAutosensDataWithWaitForCalculationFinish(reason: String): AutosensData?
|
||||
|
||||
fun calculateIobArrayInDia(profile: Profile): Array<IobTotal>
|
||||
fun calculateAbsInsulinFromTreatmentsAndTempsSynchronized(fromTime: Long): IobTotal
|
||||
fun calculateFromTreatmentsAndTempsSynchronized(time: Long, profile: Profile): IobTotal
|
||||
|
||||
fun getBasalData(profile: Profile, fromTime: Long): BasalData
|
||||
fun calculateIobArrayForSMB(lastAutosensResult: AutosensResult, exercise_mode: Boolean, half_basal_exercise_target: Int, isTempTarget: Boolean): Array<IobTotal>
|
||||
fun iobArrayToString(array: Array<IobTotal>): String
|
||||
fun slowAbsorptionPercentage(timeInMinutes: Int): Double
|
||||
fun convertToJSONArray(iobArray: Array<IobTotal>): JSONArray
|
||||
|
||||
|
||||
/**
|
||||
* Return last valid (>39) GlucoseValue from database or null if db is empty
|
||||
*
|
||||
|
@ -46,11 +49,11 @@ interface IobCobCalculator {
|
|||
/**
|
||||
* Calculate CobInfo to now()
|
||||
*
|
||||
* @param _synchronized access autosens data synchronized (wait for result if calculation is running)
|
||||
* @param waitForCalculationFinish access autosens data synchronized (wait for result if calculation is running)
|
||||
* @param reason caller identification
|
||||
* @return CobInfo
|
||||
*/
|
||||
fun getCobInfo(_synchronized: Boolean, reason: String): CobInfo
|
||||
fun getCobInfo(waitForCalculationFinish: Boolean, reason: String): CobInfo
|
||||
|
||||
/**
|
||||
* Provide last GlucoseValue or null if none exists withing last 9 minutes
|
||||
|
@ -97,7 +100,7 @@ interface IobCobCalculator {
|
|||
*
|
||||
* Running basal is added to the IOB !!!
|
||||
*
|
||||
* @param timestamp
|
||||
* @param toTime
|
||||
* @return IobTotal
|
||||
*/
|
||||
fun calculateAbsoluteIobTempBasals(toTime: Long): IobTotal
|
||||
|
@ -105,7 +108,7 @@ interface IobCobCalculator {
|
|||
/**
|
||||
* Calculate IOB from Temporary basals and Extended boluses (if emulation is enabled) to the the time specified
|
||||
*
|
||||
* @param time time to calculate to
|
||||
* @param toTime time to calculate to
|
||||
* @return IobTotal
|
||||
*/
|
||||
fun calculateIobToTimeFromTempBasalsIncludingConvertedExtended(toTime: Long): IobTotal
|
||||
|
|
|
@ -20,86 +20,84 @@ class GlucoseStatusProvider @Inject constructor(
|
|||
get() = getGlucoseStatusData()
|
||||
|
||||
fun getGlucoseStatusData(allowOldData: Boolean = false): GlucoseStatus? {
|
||||
synchronized(iobCobCalculator.dataLock) {
|
||||
val data = iobCobCalculator.bgReadings
|
||||
val sizeRecords = data.size
|
||||
if (sizeRecords == 0) {
|
||||
aapsLogger.debug(LTag.GLUCOSE, "sizeRecords==0")
|
||||
return null
|
||||
}
|
||||
if (data[0].timestamp < dateUtil.now() - 7 * 60 * 1000L && !allowOldData) {
|
||||
aapsLogger.debug(LTag.GLUCOSE, "oldData")
|
||||
return null
|
||||
}
|
||||
val now = data[0]
|
||||
val nowDate = now.timestamp
|
||||
var change: Double
|
||||
if (sizeRecords == 1) {
|
||||
aapsLogger.debug(LTag.GLUCOSE, "sizeRecords==1")
|
||||
return GlucoseStatus(
|
||||
glucose = now.value,
|
||||
noise = 0.0,
|
||||
delta = 0.0,
|
||||
shortAvgDelta = 0.0,
|
||||
longAvgDelta = 0.0,
|
||||
date = nowDate
|
||||
).asRounded()
|
||||
}
|
||||
val nowValueList = ArrayList<Double>()
|
||||
val lastDeltas = ArrayList<Double>()
|
||||
val shortDeltas = ArrayList<Double>()
|
||||
val longDeltas = ArrayList<Double>()
|
||||
|
||||
// Use the latest sgv value in the now calculations
|
||||
nowValueList.add(now.value)
|
||||
for (i in 1 until sizeRecords) {
|
||||
if (data[i].value > 38) {
|
||||
val then = data[i]
|
||||
val thenDate = then.timestamp
|
||||
|
||||
val minutesAgo = ((nowDate - thenDate) / (1000.0 * 60)).roundToLong()
|
||||
// multiply by 5 to get the same units as delta, i.e. mg/dL/5m
|
||||
change = now.value - then.value
|
||||
val avgDel = change / minutesAgo * 5
|
||||
aapsLogger.debug(LTag.GLUCOSE, "$then minutesAgo=$minutesAgo avgDelta=$avgDel")
|
||||
|
||||
// use the average of all data points in the last 2.5m for all further "now" calculations
|
||||
if (0 < minutesAgo && minutesAgo < 2.5) {
|
||||
// Keep and average all values within the last 2.5 minutes
|
||||
nowValueList.add(then.value)
|
||||
now.value = average(nowValueList)
|
||||
// short_deltas are calculated from everything ~5-15 minutes ago
|
||||
} else if (2.5 < minutesAgo && minutesAgo < 17.5) {
|
||||
//console.error(minutesAgo, avgDelta);
|
||||
shortDeltas.add(avgDel)
|
||||
// last_deltas are calculated from everything ~5 minutes ago
|
||||
if (2.5 < minutesAgo && minutesAgo < 7.5) {
|
||||
lastDeltas.add(avgDel)
|
||||
}
|
||||
// long_deltas are calculated from everything ~20-40 minutes ago
|
||||
} else if (17.5 < minutesAgo && minutesAgo < 42.5) {
|
||||
longDeltas.add(avgDel)
|
||||
} else {
|
||||
// Do not process any more records after >= 42.5 minutes
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
val shortAverageDelta = average(shortDeltas)
|
||||
val delta = if (lastDeltas.isEmpty()) {
|
||||
shortAverageDelta
|
||||
} else {
|
||||
average(lastDeltas)
|
||||
}
|
||||
val data = iobCobCalculator.getBgReadingsDataTableCopy()
|
||||
val sizeRecords = data.size
|
||||
if (sizeRecords == 0) {
|
||||
aapsLogger.debug(LTag.GLUCOSE, "sizeRecords==0")
|
||||
return null
|
||||
}
|
||||
if (data[0].timestamp < dateUtil.now() - 7 * 60 * 1000L && !allowOldData) {
|
||||
aapsLogger.debug(LTag.GLUCOSE, "oldData")
|
||||
return null
|
||||
}
|
||||
val now = data[0]
|
||||
val nowDate = now.timestamp
|
||||
var change: Double
|
||||
if (sizeRecords == 1) {
|
||||
aapsLogger.debug(LTag.GLUCOSE, "sizeRecords==1")
|
||||
return GlucoseStatus(
|
||||
glucose = now.value,
|
||||
date = nowDate,
|
||||
noise = 0.0, //for now set to nothing as not all CGMs report noise
|
||||
shortAvgDelta = shortAverageDelta,
|
||||
delta = delta,
|
||||
longAvgDelta = average(longDeltas),
|
||||
).also { aapsLogger.debug(LTag.GLUCOSE, it.log()) }.asRounded()
|
||||
noise = 0.0,
|
||||
delta = 0.0,
|
||||
shortAvgDelta = 0.0,
|
||||
longAvgDelta = 0.0,
|
||||
date = nowDate
|
||||
).asRounded()
|
||||
}
|
||||
val nowValueList = ArrayList<Double>()
|
||||
val lastDeltas = ArrayList<Double>()
|
||||
val shortDeltas = ArrayList<Double>()
|
||||
val longDeltas = ArrayList<Double>()
|
||||
|
||||
// Use the latest sgv value in the now calculations
|
||||
nowValueList.add(now.value)
|
||||
for (i in 1 until sizeRecords) {
|
||||
if (data[i].value > 38) {
|
||||
val then = data[i]
|
||||
val thenDate = then.timestamp
|
||||
|
||||
val minutesAgo = ((nowDate - thenDate) / (1000.0 * 60)).roundToLong()
|
||||
// multiply by 5 to get the same units as delta, i.e. mg/dL/5m
|
||||
change = now.value - then.value
|
||||
val avgDel = change / minutesAgo * 5
|
||||
aapsLogger.debug(LTag.GLUCOSE, "$then minutesAgo=$minutesAgo avgDelta=$avgDel")
|
||||
|
||||
// use the average of all data points in the last 2.5m for all further "now" calculations
|
||||
if (0 < minutesAgo && minutesAgo < 2.5) {
|
||||
// Keep and average all values within the last 2.5 minutes
|
||||
nowValueList.add(then.value)
|
||||
now.value = average(nowValueList)
|
||||
// short_deltas are calculated from everything ~5-15 minutes ago
|
||||
} else if (2.5 < minutesAgo && minutesAgo < 17.5) {
|
||||
//console.error(minutesAgo, avgDelta);
|
||||
shortDeltas.add(avgDel)
|
||||
// last_deltas are calculated from everything ~5 minutes ago
|
||||
if (2.5 < minutesAgo && minutesAgo < 7.5) {
|
||||
lastDeltas.add(avgDel)
|
||||
}
|
||||
// long_deltas are calculated from everything ~20-40 minutes ago
|
||||
} else if (17.5 < minutesAgo && minutesAgo < 42.5) {
|
||||
longDeltas.add(avgDel)
|
||||
} else {
|
||||
// Do not process any more records after >= 42.5 minutes
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
val shortAverageDelta = average(shortDeltas)
|
||||
val delta = if (lastDeltas.isEmpty()) {
|
||||
shortAverageDelta
|
||||
} else {
|
||||
average(lastDeltas)
|
||||
}
|
||||
return GlucoseStatus(
|
||||
glucose = now.value,
|
||||
date = nowDate,
|
||||
noise = 0.0, //for now set to nothing as not all CGMs report noise
|
||||
shortAvgDelta = shortAverageDelta,
|
||||
delta = delta,
|
||||
longAvgDelta = average(longDeltas),
|
||||
).also { aapsLogger.debug(LTag.GLUCOSE, it.log()) }.asRounded()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -13,7 +13,6 @@ import org.junit.Before
|
|||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.`when`
|
||||
import org.powermock.api.mockito.PowerMockito
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest
|
||||
import org.powermock.modules.junit4.PowerMockRunner
|
||||
|
@ -41,7 +40,7 @@ class GlucoseStatusTest : TestBase() {
|
|||
}
|
||||
|
||||
@Test fun calculateValidGlucoseStatus() {
|
||||
PowerMockito.`when`(iobCobCalculatorPlugin.bgReadings).thenReturn(generateValidBgData())
|
||||
PowerMockito.`when`(iobCobCalculatorPlugin.getBgReadingsDataTableCopy()).thenReturn(generateValidBgData())
|
||||
val glucoseStatus = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData!!
|
||||
Assert.assertEquals(214.0, glucoseStatus.glucose, 0.001)
|
||||
Assert.assertEquals(-2.0, glucoseStatus.delta, 0.001)
|
||||
|
@ -51,7 +50,7 @@ class GlucoseStatusTest : TestBase() {
|
|||
}
|
||||
|
||||
@Test fun calculateMostRecentGlucoseStatus() {
|
||||
PowerMockito.`when`(iobCobCalculatorPlugin.bgReadings).thenReturn(generateMostRecentBgData())
|
||||
PowerMockito.`when`(iobCobCalculatorPlugin.getBgReadingsDataTableCopy()).thenReturn(generateMostRecentBgData())
|
||||
val glucoseStatus: GlucoseStatus = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData!!
|
||||
Assert.assertEquals(215.0, glucoseStatus.glucose, 0.001) // (214+216) / 2
|
||||
Assert.assertEquals(-1.0, glucoseStatus.delta, 0.001)
|
||||
|
@ -61,7 +60,7 @@ class GlucoseStatusTest : TestBase() {
|
|||
}
|
||||
|
||||
@Test fun oneRecordShouldProduceZeroDeltas() {
|
||||
PowerMockito.`when`(iobCobCalculatorPlugin.bgReadings).thenReturn(generateOneCurrentRecordBgData())
|
||||
PowerMockito.`when`(iobCobCalculatorPlugin.getBgReadingsDataTableCopy()).thenReturn(generateOneCurrentRecordBgData())
|
||||
val glucoseStatus: GlucoseStatus = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData!!
|
||||
Assert.assertEquals(214.0, glucoseStatus.glucose, 0.001)
|
||||
Assert.assertEquals(0.0, glucoseStatus.delta, 0.001)
|
||||
|
@ -71,19 +70,19 @@ class GlucoseStatusTest : TestBase() {
|
|||
}
|
||||
|
||||
@Test fun insufficientDataShouldReturnNull() {
|
||||
PowerMockito.`when`(iobCobCalculatorPlugin.bgReadings).thenReturn(generateInsufficientBgData())
|
||||
PowerMockito.`when`(iobCobCalculatorPlugin.getBgReadingsDataTableCopy()).thenReturn(generateInsufficientBgData())
|
||||
val glucoseStatus: GlucoseStatus? = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData
|
||||
Assert.assertEquals(null, glucoseStatus)
|
||||
}
|
||||
|
||||
@Test fun oldDataShouldReturnNull() {
|
||||
PowerMockito.`when`(iobCobCalculatorPlugin.bgReadings).thenReturn(generateOldBgData())
|
||||
PowerMockito.`when`(iobCobCalculatorPlugin.getBgReadingsDataTableCopy()).thenReturn(generateOldBgData())
|
||||
val glucoseStatus: GlucoseStatus? = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData
|
||||
Assert.assertEquals(null, glucoseStatus)
|
||||
}
|
||||
|
||||
@Test fun returnOldDataIfAllowed() {
|
||||
PowerMockito.`when`(iobCobCalculatorPlugin.bgReadings).thenReturn(generateOldBgData())
|
||||
PowerMockito.`when`(iobCobCalculatorPlugin.getBgReadingsDataTableCopy()).thenReturn(generateOldBgData())
|
||||
val glucoseStatus: GlucoseStatus? = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).getGlucoseStatusData(true)
|
||||
Assert.assertNotEquals(null, glucoseStatus)
|
||||
}
|
||||
|
@ -93,7 +92,7 @@ class GlucoseStatusTest : TestBase() {
|
|||
}
|
||||
|
||||
@Test fun calculateGlucoseStatusForLibreTestBgData() {
|
||||
PowerMockito.`when`(iobCobCalculatorPlugin.bgReadings).thenReturn(generateLibreTestData())
|
||||
PowerMockito.`when`(iobCobCalculatorPlugin.getBgReadingsDataTableCopy()).thenReturn(generateLibreTestData())
|
||||
val glucoseStatus: GlucoseStatus = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData!!
|
||||
Assert.assertEquals(100.0, glucoseStatus.glucose, 0.001) //
|
||||
Assert.assertEquals(-10.0, glucoseStatus.delta, 0.001)
|
||||
|
@ -105,7 +104,6 @@ class GlucoseStatusTest : TestBase() {
|
|||
@Before
|
||||
fun initMocking() {
|
||||
PowerMockito.`when`(dateUtil.now()).thenReturn(1514766900000L + T.mins(1).msecs())
|
||||
`when`(iobCobCalculatorPlugin.dataLock).thenReturn(Any())
|
||||
}
|
||||
|
||||
// [{"mgdl":214,"mills":1521895773113,"device":"xDrip-DexcomG5","direction":"Flat","filtered":191040,"unfiltered":205024,"noise":1,"rssi":100},{"mgdl":219,"mills":1521896073352,"device":"xDrip-DexcomG5","direction":"Flat","filtered":200160,"unfiltered":209760,"noise":1,"rssi":100},{"mgdl":222,"mills":1521896372890,"device":"xDrip-DexcomG5","direction":"Flat","filtered":207360,"unfiltered":212512,"noise":1,"rssi":100},{"mgdl":220,"mills":1521896673062,"device":"xDrip-DexcomG5","direction":"Flat","filtered":211488,"unfiltered":210688,"noise":1,"rssi":100},{"mgdl":193,"mills":1521896972933,"device":"xDrip-DexcomG5","direction":"Flat","filtered":212384,"unfiltered":208960,"noise":1,"rssi":100},{"mgdl":181,"mills":1521897273336,"device":"xDrip-DexcomG5","direction":"SingleDown","filtered":210592,"unfiltered":204320,"noise":1,"rssi":100},{"mgdl":176,"mills":1521897572875,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":206720,"unfiltered":197440,"noise":1,"rssi":100},{"mgdl":168,"mills":1521897872929,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":201024,"unfiltered":187904,"noise":1,"rssi":100},{"mgdl":161,"mills":1521898172814,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":193376,"unfiltered":178144,"noise":1,"rssi":100},{"mgdl":148,"mills":1521898472879,"device":"xDrip-DexcomG5","direction":"SingleDown","filtered":183264,"unfiltered":161216,"noise":1,"rssi":100},{"mgdl":139,"mills":1521898772862,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":170784,"unfiltered":148928,"noise":1,"rssi":100},{"mgdl":132,"mills":1521899072896,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":157248,"unfiltered":139552,"noise":1,"rssi":100},{"mgdl":125,"mills":1521899372834,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":144416,"unfiltered":129616.00000000001,"noise":1,"rssi":100},{"mgdl":128,"mills":1521899973456,"device":"xDrip-DexcomG5","direction":"Flat","filtered":130240.00000000001,"unfiltered":133536,"noise":1,"rssi":100},{"mgdl":132,"mills":1521900573287,"device":"xDrip-DexcomG5","direction":"Flat","filtered":133504,"unfiltered":138720,"noise":1,"rssi":100},{"mgdl":127,"mills":1521900873711,"device":"xDrip-DexcomG5","direction":"Flat","filtered":136480,"unfiltered":132992,"noise":1,"rssi":100},{"mgdl":127,"mills":1521901180151,"device":"xDrip-DexcomG5","direction":"Flat","filtered":136896,"unfiltered":132128,"noise":1,"rssi":100},{"mgdl":125,"mills":1521901473582,"device":"xDrip-DexcomG5","direction":"Flat","filtered":134624,"unfiltered":129696,"noise":1,"rssi":100},{"mgdl":120,"mills":1521901773597,"device":"xDrip-DexcomG5","direction":"Flat","filtered":130704.00000000001,"unfiltered":123376,"noise":1,"rssi":100},{"mgdl":116,"mills":1521902075855,"device":"xDrip-DexcomG5","direction":"Flat","filtered":126272,"unfiltered":118448,"noise":1,"rssi":100}]
|
||||
|
|
Loading…
Reference in a new issue