cache last DataStore object for bolus wizard
This commit is contained in:
parent
c802e7e4a2
commit
86edb3dfae
|
@ -32,11 +32,10 @@ interface IobCobCalculator {
|
||||||
/**
|
/**
|
||||||
* Calculate CobInfo to now()
|
* Calculate CobInfo to now()
|
||||||
*
|
*
|
||||||
* @param waitForCalculationFinish access autosens data synchronized (wait for result if calculation is running)
|
|
||||||
* @param reason caller identification
|
* @param reason caller identification
|
||||||
* @return CobInfo
|
* @return CobInfo
|
||||||
*/
|
*/
|
||||||
fun getCobInfo(waitForCalculationFinish: Boolean, reason: String): CobInfo
|
fun getCobInfo(reason: String): CobInfo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate IobTotal from boluses and extended boluses to now().
|
* Calculate IobTotal from boluses and extended boluses to now().
|
||||||
|
|
|
@ -107,7 +107,7 @@ class QuickWizardEntry @Inject constructor(private val injector: HasAndroidInjec
|
||||||
|
|
||||||
fun isActive(): Boolean = time.secondsFromMidnight() >= validFrom() && time.secondsFromMidnight() <= validTo() && forDevice(DEVICE_PHONE)
|
fun isActive(): Boolean = time.secondsFromMidnight() >= validFrom() && time.secondsFromMidnight() <= validTo() && forDevice(DEVICE_PHONE)
|
||||||
|
|
||||||
fun doCalc(profile: Profile, profileName: String, lastBG: InMemoryGlucoseValue, _synchronized: Boolean): BolusWizard {
|
fun doCalc(profile: Profile, profileName: String, lastBG: InMemoryGlucoseValue): BolusWizard {
|
||||||
val dbRecord = persistenceLayer.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet()
|
val dbRecord = persistenceLayer.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet()
|
||||||
val tempTarget = if (dbRecord is ValueWrapper.Existing) dbRecord.value else null
|
val tempTarget = if (dbRecord is ValueWrapper.Existing) dbRecord.value else null
|
||||||
//BG
|
//BG
|
||||||
|
@ -117,7 +117,7 @@ class QuickWizardEntry @Inject constructor(private val injector: HasAndroidInjec
|
||||||
}
|
}
|
||||||
// COB
|
// COB
|
||||||
val cob =
|
val cob =
|
||||||
if (useCOB() == YES) iobCobCalculator.getCobInfo(_synchronized, "QuickWizard COB").displayCob ?: 0.0
|
if (useCOB() == YES) iobCobCalculator.getCobInfo("QuickWizard COB").displayCob ?: 0.0
|
||||||
else 0.0
|
else 0.0
|
||||||
// Bolus IOB
|
// Bolus IOB
|
||||||
var bolusIOB = false
|
var bolusIOB = false
|
||||||
|
|
|
@ -219,7 +219,7 @@ class OverviewDataImpl @Inject constructor(
|
||||||
|
|
||||||
override fun bolusIob(iobCobCalculator: IobCobCalculator): IobTotal = iobCobCalculator.calculateIobFromBolus().round()
|
override fun bolusIob(iobCobCalculator: IobCobCalculator): IobTotal = iobCobCalculator.calculateIobFromBolus().round()
|
||||||
override fun basalIob(iobCobCalculator: IobCobCalculator): IobTotal = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round()
|
override fun basalIob(iobCobCalculator: IobCobCalculator): IobTotal = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round()
|
||||||
override fun cobInfo(iobCobCalculator: IobCobCalculator): CobInfo = iobCobCalculator.getCobInfo(true, "Overview COB")
|
override fun cobInfo(iobCobCalculator: IobCobCalculator): CobInfo = iobCobCalculator.getCobInfo("Overview COB")
|
||||||
|
|
||||||
override val lastCarbsTime: Long
|
override val lastCarbsTime: Long
|
||||||
get() = repository.getLastCarbsRecordWrapped().blockingGet().let { lastCarbs ->
|
get() = repository.getLastCarbsRecordWrapped().blockingGet().let { lastCarbs ->
|
||||||
|
|
|
@ -38,7 +38,7 @@ class TriggerCOB(injector: HasAndroidInjector) : Trigger(injector) {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun shouldRun(): Boolean {
|
override fun shouldRun(): Boolean {
|
||||||
val cobInfo = iobCobCalculator.getCobInfo(false, "AutomationTriggerCOB")
|
val cobInfo = iobCobCalculator.getCobInfo("AutomationTriggerCOB")
|
||||||
if (cobInfo.displayCob == null) {
|
if (cobInfo.displayCob == null) {
|
||||||
return if (comparator.value === Comparator.Compare.IS_NOT_AVAILABLE) {
|
return if (comparator.value === Comparator.Compare.IS_NOT_AVAILABLE) {
|
||||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||||
|
|
|
@ -21,7 +21,7 @@ class TriggerCOBTest : TriggerTestBase() {
|
||||||
|
|
||||||
@Test fun shouldRunTest() {
|
@Test fun shouldRunTest() {
|
||||||
// COB value is 6
|
// COB value is 6
|
||||||
`when`(iobCobCalculator.getCobInfo(false, "AutomationTriggerCOB")).thenReturn(CobInfo(0, 6.0, 2.0))
|
`when`(iobCobCalculator.getCobInfo("AutomationTriggerCOB")).thenReturn(CobInfo(0, 6.0, 2.0))
|
||||||
var t: TriggerCOB = TriggerCOB(injector).setValue(1.0).comparator(Comparator.Compare.IS_EQUAL)
|
var t: TriggerCOB = TriggerCOB(injector).setValue(1.0).comparator(Comparator.Compare.IS_EQUAL)
|
||||||
Assert.assertFalse(t.shouldRun())
|
Assert.assertFalse(t.shouldRun())
|
||||||
t = TriggerCOB(injector).setValue(6.0).comparator(Comparator.Compare.IS_EQUAL)
|
t = TriggerCOB(injector).setValue(6.0).comparator(Comparator.Compare.IS_EQUAL)
|
||||||
|
|
|
@ -133,7 +133,7 @@ class DataBroadcastPlugin @Inject constructor(
|
||||||
bundle.putDouble("basalIob", basalIob.basaliob)
|
bundle.putDouble("basalIob", basalIob.basaliob)
|
||||||
bundle.putDouble("iob", bolusIob.iob + basalIob.basaliob) // total IOB
|
bundle.putDouble("iob", bolusIob.iob + basalIob.basaliob) // total IOB
|
||||||
|
|
||||||
val cob = iobCobCalculator.getCobInfo(false, "broadcast")
|
val cob = iobCobCalculator.getCobInfo("broadcast")
|
||||||
bundle.putDouble("cob", cob.displayCob ?: -1.0) // COB [g] or -1 if N/A
|
bundle.putDouble("cob", cob.displayCob ?: -1.0) // COB [g] or -1 if N/A
|
||||||
bundle.putDouble("futureCarbs", cob.futureCarbs) // future scheduled carbs
|
bundle.putDouble("futureCarbs", cob.futureCarbs) // future scheduled carbs
|
||||||
}
|
}
|
||||||
|
|
|
@ -511,7 +511,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
val quickWizardEntry = quickWizard.getActive()
|
val quickWizardEntry = quickWizard.getActive()
|
||||||
if (quickWizardEntry != null && actualBg != null && profile != null) {
|
if (quickWizardEntry != null && actualBg != null && profile != null) {
|
||||||
binding.buttonsLayout.quickWizardButton.visibility = View.VISIBLE
|
binding.buttonsLayout.quickWizardButton.visibility = View.VISIBLE
|
||||||
val wizard = quickWizardEntry.doCalc(profile, profileName, actualBg, true)
|
val wizard = quickWizardEntry.doCalc(profile, profileName, actualBg)
|
||||||
if (wizard.calculatedTotalInsulin > 0.0 && quickWizardEntry.carbs() > 0.0) {
|
if (wizard.calculatedTotalInsulin > 0.0 && quickWizardEntry.carbs() > 0.0) {
|
||||||
val carbsAfterConstraints = constraintChecker.applyCarbsConstraints(Constraint(quickWizardEntry.carbs())).value()
|
val carbsAfterConstraints = constraintChecker.applyCarbsConstraints(Constraint(quickWizardEntry.carbs())).value()
|
||||||
activity?.let {
|
activity?.let {
|
||||||
|
@ -539,7 +539,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
_binding ?: return@runOnUiThread
|
_binding ?: return@runOnUiThread
|
||||||
if (quickWizardEntry != null && lastBG != null && profile != null && pump.isInitialized() && !pump.isSuspended() && !loop.isDisconnected) {
|
if (quickWizardEntry != null && lastBG != null && profile != null && pump.isInitialized() && !pump.isSuspended() && !loop.isDisconnected) {
|
||||||
binding.buttonsLayout.quickWizardButton.visibility = View.VISIBLE
|
binding.buttonsLayout.quickWizardButton.visibility = View.VISIBLE
|
||||||
val wizard = quickWizardEntry.doCalc(profile, profileName, lastBG, false)
|
val wizard = quickWizardEntry.doCalc(profile, profileName, lastBG)
|
||||||
binding.buttonsLayout.quickWizardButton.text = quickWizardEntry.buttonText() + "\n" + rh.gs(info.nightscout.core.graph.R.string.format_carbs, quickWizardEntry.carbs()) +
|
binding.buttonsLayout.quickWizardButton.text = quickWizardEntry.buttonText() + "\n" + rh.gs(info.nightscout.core.graph.R.string.format_carbs, quickWizardEntry.carbs()) +
|
||||||
" " + rh.gs(info.nightscout.interfaces.R.string.format_insulin_units, wizard.calculatedTotalInsulin)
|
" " + rh.gs(info.nightscout.interfaces.R.string.format_insulin_units, wizard.calculatedTotalInsulin)
|
||||||
if (wizard.calculatedTotalInsulin <= 0) binding.buttonsLayout.quickWizardButton.visibility = View.GONE
|
if (wizard.calculatedTotalInsulin <= 0) binding.buttonsLayout.quickWizardButton.visibility = View.GONE
|
||||||
|
|
|
@ -148,12 +148,10 @@ class PersistentNotificationPlugin @Inject constructor(
|
||||||
val basalIob = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round()
|
val basalIob = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round()
|
||||||
line2 =
|
line2 =
|
||||||
rh.gs(info.nightscout.core.ui.R.string.treatments_iob_label_string) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U " + rh.gs(info.nightscout.core.ui.R.string.cob) + ": " + iobCobCalculator.getCobInfo(
|
rh.gs(info.nightscout.core.ui.R.string.treatments_iob_label_string) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U " + rh.gs(info.nightscout.core.ui.R.string.cob) + ": " + iobCobCalculator.getCobInfo(
|
||||||
false,
|
|
||||||
"PersistentNotificationPlugin"
|
"PersistentNotificationPlugin"
|
||||||
).generateCOBString()
|
).generateCOBString()
|
||||||
val line2aa =
|
val line2aa =
|
||||||
rh.gs(info.nightscout.core.ui.R.string.treatments_iob_label_string) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U. " + rh.gs(info.nightscout.core.ui.R.string.cob) + ": " + iobCobCalculator.getCobInfo(
|
rh.gs(info.nightscout.core.ui.R.string.treatments_iob_label_string) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U. " + rh.gs(info.nightscout.core.ui.R.string.cob) + ": " + iobCobCalculator.getCobInfo(
|
||||||
false,
|
|
||||||
"PersistentNotificationPlugin"
|
"PersistentNotificationPlugin"
|
||||||
).generateCOBString() + "."
|
).generateCOBString() + "."
|
||||||
line3 = DecimalFormatter.to2Decimal(pump.baseBasalRate) + " U/h"
|
line3 = DecimalFormatter.to2Decimal(pump.baseBasalRate) + " U/h"
|
||||||
|
|
|
@ -365,7 +365,7 @@ class SmsCommunicatorPlugin @Inject constructor(
|
||||||
if (glucoseStatus != null) reply += rh.gs(R.string.sms_delta) + " " + Profile.toUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) + " " + units + ", "
|
if (glucoseStatus != null) reply += rh.gs(R.string.sms_delta) + " " + Profile.toUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) + " " + units + ", "
|
||||||
val bolusIob = iobCobCalculator.calculateIobFromBolus().round()
|
val bolusIob = iobCobCalculator.calculateIobFromBolus().round()
|
||||||
val basalIob = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round()
|
val basalIob = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round()
|
||||||
val cobInfo = iobCobCalculator.getCobInfo(false, "SMS COB")
|
val cobInfo = iobCobCalculator.getCobInfo("SMS COB")
|
||||||
reply += (rh.gs(R.string.sms_iob) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U ("
|
reply += (rh.gs(R.string.sms_iob) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U ("
|
||||||
+ rh.gs(R.string.sms_bolus) + " " + DecimalFormatter.to2Decimal(bolusIob.iob) + "U "
|
+ rh.gs(R.string.sms_bolus) + " " + DecimalFormatter.to2Decimal(bolusIob.iob) + "U "
|
||||||
+ rh.gs(R.string.sms_basal) + " " + DecimalFormatter.to2Decimal(basalIob.basaliob) + "U), "
|
+ rh.gs(R.string.sms_basal) + " " + DecimalFormatter.to2Decimal(basalIob.basaliob) + "U), "
|
||||||
|
|
|
@ -16,7 +16,13 @@ import info.nightscout.core.wizard.BolusWizard
|
||||||
import info.nightscout.core.wizard.QuickWizard
|
import info.nightscout.core.wizard.QuickWizard
|
||||||
import info.nightscout.core.wizard.QuickWizardEntry
|
import info.nightscout.core.wizard.QuickWizardEntry
|
||||||
import info.nightscout.database.ValueWrapper
|
import info.nightscout.database.ValueWrapper
|
||||||
import info.nightscout.database.entities.*
|
import info.nightscout.database.entities.Bolus
|
||||||
|
import info.nightscout.database.entities.GlucoseValue
|
||||||
|
import info.nightscout.database.entities.TemporaryBasal
|
||||||
|
import info.nightscout.database.entities.TemporaryTarget
|
||||||
|
import info.nightscout.database.entities.TotalDailyDose
|
||||||
|
import info.nightscout.database.entities.UserEntry
|
||||||
|
import info.nightscout.database.entities.ValueWithUnit
|
||||||
import info.nightscout.database.entities.interfaces.end
|
import info.nightscout.database.entities.interfaces.end
|
||||||
import info.nightscout.database.impl.AppRepository
|
import info.nightscout.database.impl.AppRepository
|
||||||
import info.nightscout.database.impl.transactions.CancelCurrentTemporaryTargetIfAnyTransaction
|
import info.nightscout.database.impl.transactions.CancelCurrentTemporaryTargetIfAnyTransaction
|
||||||
|
@ -60,7 +66,9 @@ import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||||
import io.reactivex.rxjava3.kotlin.plusAssign
|
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||||
import java.text.DateFormat
|
import java.text.DateFormat
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.Date
|
||||||
|
import java.util.LinkedList
|
||||||
|
import java.util.Locale
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import java.util.stream.Collectors
|
import java.util.stream.Collectors
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -369,7 +377,7 @@ class DataHandlerMobile @Inject constructor(
|
||||||
sendError(rh.gs(info.nightscout.core.ui.R.string.wizard_no_actual_bg))
|
sendError(rh.gs(info.nightscout.core.ui.R.string.wizard_no_actual_bg))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val cobInfo = iobCobCalculator.getCobInfo(false, "Wizard wear")
|
val cobInfo = iobCobCalculator.getCobInfo("Wizard wear")
|
||||||
if (cobInfo.displayCob == null) {
|
if (cobInfo.displayCob == null) {
|
||||||
sendError(rh.gs(info.nightscout.core.ui.R.string.wizard_no_cob))
|
sendError(rh.gs(info.nightscout.core.ui.R.string.wizard_no_cob))
|
||||||
return
|
return
|
||||||
|
@ -436,7 +444,7 @@ class DataHandlerMobile @Inject constructor(
|
||||||
sendError(rh.gs(info.nightscout.core.ui.R.string.wizard_no_active_profile))
|
sendError(rh.gs(info.nightscout.core.ui.R.string.wizard_no_active_profile))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val cobInfo = iobCobCalculator.getCobInfo(false, "QuickWizard wear")
|
val cobInfo = iobCobCalculator.getCobInfo("QuickWizard wear")
|
||||||
if (cobInfo.displayCob == null) {
|
if (cobInfo.displayCob == null) {
|
||||||
sendError(rh.gs(info.nightscout.core.ui.R.string.wizard_no_cob))
|
sendError(rh.gs(info.nightscout.core.ui.R.string.wizard_no_cob))
|
||||||
return
|
return
|
||||||
|
@ -447,7 +455,7 @@ class DataHandlerMobile @Inject constructor(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val wizard = quickWizardEntry.doCalc(profile, profileName, actualBg, true)
|
val wizard = quickWizardEntry.doCalc(profile, profileName, actualBg)
|
||||||
|
|
||||||
val carbsAfterConstraints = constraintChecker.applyCarbsConstraints(Constraint(quickWizardEntry.carbs())).value()
|
val carbsAfterConstraints = constraintChecker.applyCarbsConstraints(Constraint(quickWizardEntry.carbs())).value()
|
||||||
if (carbsAfterConstraints != quickWizardEntry.carbs()) {
|
if (carbsAfterConstraints != quickWizardEntry.carbs()) {
|
||||||
|
@ -877,7 +885,7 @@ class DataHandlerMobile @Inject constructor(
|
||||||
val basalIob = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round()
|
val basalIob = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round()
|
||||||
iobSum = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob)
|
iobSum = DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob)
|
||||||
iobDetail = "(${DecimalFormatter.to2Decimal(bolusIob.iob)}|${DecimalFormatter.to2Decimal(basalIob.basaliob)})"
|
iobDetail = "(${DecimalFormatter.to2Decimal(bolusIob.iob)}|${DecimalFormatter.to2Decimal(basalIob.basaliob)})"
|
||||||
cobString = iobCobCalculator.getCobInfo(false, "WatcherUpdaterService").generateCOBString()
|
cobString = iobCobCalculator.getCobInfo("WatcherUpdaterService").generateCOBString()
|
||||||
currentBasal =
|
currentBasal =
|
||||||
iobCobCalculator.getTempBasalIncludingConvertedExtended(System.currentTimeMillis())?.toStringShort() ?: rh.gs(info.nightscout.core.ui.R.string.pump_base_basal_rate, profile.getBasal())
|
iobCobCalculator.getTempBasalIncludingConvertedExtended(System.currentTimeMillis())?.toStringShort() ?: rh.gs(info.nightscout.core.ui.R.string.pump_base_basal_rate, profile.getBasal())
|
||||||
|
|
||||||
|
|
|
@ -151,7 +151,7 @@ class StatusLinePlugin @Inject constructor(
|
||||||
status += " " + (if (bgi >= 0) "+" else "") + DecimalFormatter.to2Decimal(bgi)
|
status += " " + (if (bgi >= 0) "+" else "") + DecimalFormatter.to2Decimal(bgi)
|
||||||
}
|
}
|
||||||
// COB
|
// COB
|
||||||
status += " " + iobCobCalculator.getCobInfo(false, "StatusLinePlugin").generateCOBString()
|
status += " " + iobCobCalculator.getCobInfo("StatusLinePlugin").generateCOBString()
|
||||||
return status
|
return status
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -292,10 +292,8 @@ class IobCobCalculatorPlugin @Inject constructor(
|
||||||
return ads.getLastAutosensData(reason, aapsLogger, dateUtil)
|
return ads.getLastAutosensData(reason, aapsLogger, dateUtil)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getCobInfo(waitForCalculationFinish: Boolean, reason: String): CobInfo {
|
override fun getCobInfo(reason: String): CobInfo {
|
||||||
val autosensData =
|
val autosensData = ads.getLastAutosensData(reason, aapsLogger, dateUtil)
|
||||||
if (waitForCalculationFinish) getLastAutosensDataWithWaitForCalculationFinish(reason)
|
|
||||||
else ads.getLastAutosensData(reason, aapsLogger, dateUtil)
|
|
||||||
var displayCob: Double? = null
|
var displayCob: Double? = null
|
||||||
var futureCarbs = 0.0
|
var futureCarbs = 0.0
|
||||||
val now = dateUtil.now()
|
val now = dateUtil.now()
|
||||||
|
|
|
@ -116,30 +116,34 @@ class AutosensDataStoreObject : AutosensDataStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// during recalculation autosensDataTable is cleared and not available
|
||||||
|
// for providing COB, which is an serious issue in BolusWizard
|
||||||
|
// So let save last value after every calculation and use it
|
||||||
|
// if autosensDataTable is not available
|
||||||
|
var storedLastAutosensResult: AutosensData? = null
|
||||||
|
get() = field?.let { if (it.time < System.currentTimeMillis() - 11 * 60 * 1000) it else null }
|
||||||
|
|
||||||
override fun getLastAutosensData(reason: String, aapsLogger: AAPSLogger, dateUtil: DateUtil): AutosensData? {
|
override fun getLastAutosensData(reason: String, aapsLogger: AAPSLogger, dateUtil: DateUtil): AutosensData? {
|
||||||
synchronized(dataLock) {
|
synchronized(dataLock) {
|
||||||
if (autosensDataTable.size() < 1) {
|
if (autosensDataTable.size() < 1) {
|
||||||
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA null: autosensDataTable empty ($reason)")
|
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA null: autosensDataTable empty ($reason)")
|
||||||
return null
|
return storedLastAutosensResult
|
||||||
}
|
}
|
||||||
val data: AutosensData? = try {
|
val data: AutosensData = try {
|
||||||
autosensDataTable.valueAt(autosensDataTable.size() - 1)
|
autosensDataTable.valueAt(autosensDataTable.size() - 1)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
// data can be processed on the background
|
// data can be processed on the background
|
||||||
// in this rare case better return null and do not block UI
|
// in this rare case better return null and do not block UI
|
||||||
// APS plugin should use getLastAutosensDataSynchronized where the blocking is not an issue
|
// APS plugin should use getLastAutosensDataSynchronized where the blocking is not an issue
|
||||||
aapsLogger.error("AUTOSENSDATA null: Exception caught ($reason)")
|
aapsLogger.error("AUTOSENSDATA null: Exception caught ($reason)")
|
||||||
return null
|
return storedLastAutosensResult
|
||||||
}
|
}
|
||||||
if (data == null) {
|
return if (data.time < dateUtil.now() - 11 * 60 * 1000) {
|
||||||
aapsLogger.error("AUTOSENSDATA null: data==null")
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
return if (data.time < System.currentTimeMillis() - 11 * 60 * 1000) {
|
|
||||||
aapsLogger.debug(LTag.AUTOSENS) { "AUTOSENSDATA null: data is old ($reason) size()=${autosensDataTable.size()} lastData=${dateUtil.dateAndTimeAndSecondsString(data.time)}" }
|
aapsLogger.debug(LTag.AUTOSENS) { "AUTOSENSDATA null: data is old ($reason) size()=${autosensDataTable.size()} lastData=${dateUtil.dateAndTimeAndSecondsString(data.time)}" }
|
||||||
null
|
storedLastAutosensResult
|
||||||
} else {
|
} else {
|
||||||
aapsLogger.debug(LTag.AUTOSENS) { "AUTOSENSDATA ($reason) $data" }
|
aapsLogger.debug(LTag.AUTOSENS) { "AUTOSENSDATA ($reason) $data" }
|
||||||
|
storedLastAutosensResult = data
|
||||||
data
|
data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,11 +156,8 @@ class AutosensDataStoreObject : AutosensDataStore {
|
||||||
}
|
}
|
||||||
var diff = abs(someTime - referenceTime)
|
var diff = abs(someTime - referenceTime)
|
||||||
diff %= T.mins(5).msecs()
|
diff %= T.mins(5).msecs()
|
||||||
if (diff > T.mins(2).plus(T.secs(30)).msecs()){
|
return if (diff > T.mins(2).plus(T.secs(30)).msecs()) someTime + abs(diff - T.mins(5).msecs()) // Adjust to the future
|
||||||
return someTime + abs(diff - T.mins(5).msecs()) // Adjust to the future
|
else someTime - diff // adjust to the past
|
||||||
} else {
|
|
||||||
return someTime - diff // adjust to the past
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isAbout5minData(aapsLogger: AAPSLogger): Boolean {
|
fun isAbout5minData(aapsLogger: AAPSLogger): Boolean {
|
||||||
|
|
|
@ -97,7 +97,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
||||||
val bgList: MutableList<GlucoseValue> = ArrayList()
|
val bgList: MutableList<GlucoseValue> = ArrayList()
|
||||||
bgList.add(reading)
|
bgList.add(reading)
|
||||||
|
|
||||||
`when`(iobCobCalculator.getCobInfo(false, "SMS COB")).thenReturn(CobInfo(0, 10.0, 2.0))
|
`when`(iobCobCalculator.getCobInfo("SMS COB")).thenReturn(CobInfo(0, 10.0, 2.0))
|
||||||
`when`(iobCobCalculator.ads).thenReturn(autosensDataStore)
|
`when`(iobCobCalculator.ads).thenReturn(autosensDataStore)
|
||||||
`when`(autosensDataStore.lastBg()).thenReturn(InMemoryGlucoseValue(reading))
|
`when`(autosensDataStore.lastBg()).thenReturn(InMemoryGlucoseValue(reading))
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,48 @@
|
||||||
package info.nightscout.plugins.iob
|
package info.nightscout.plugins.iob
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import androidx.collection.LongSparseArray
|
||||||
|
import dagger.android.AndroidInjector
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.TestBase
|
import info.nightscout.androidaps.TestBase
|
||||||
import info.nightscout.database.entities.GlucoseValue
|
import info.nightscout.database.entities.GlucoseValue
|
||||||
|
import info.nightscout.interfaces.aps.AutosensData
|
||||||
|
import info.nightscout.interfaces.profile.ProfileFunction
|
||||||
|
import info.nightscout.plugins.iob.iobCobCalculator.data.AutosensDataObject
|
||||||
|
import info.nightscout.plugins.iob.iobCobCalculator.data.AutosensDataStoreObject
|
||||||
|
import info.nightscout.shared.interfaces.ResourceHelper
|
||||||
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
import info.nightscout.shared.utils.DateUtil
|
import info.nightscout.shared.utils.DateUtil
|
||||||
import info.nightscout.shared.utils.T
|
import info.nightscout.shared.utils.T
|
||||||
import org.junit.jupiter.api.Assertions
|
import org.junit.jupiter.api.Assertions
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
|
import org.mockito.Mockito
|
||||||
|
|
||||||
class AutosensDataStoreTest : TestBase() {
|
class AutosensDataStoreTest : TestBase() {
|
||||||
|
|
||||||
@Mock lateinit var context: Context
|
@Mock lateinit var context: Context
|
||||||
|
@Mock lateinit var sp: SP
|
||||||
|
@Mock lateinit var rh: ResourceHelper
|
||||||
|
@Mock lateinit var profileFunction: ProfileFunction
|
||||||
|
@Mock lateinit var dateUtilMocked: DateUtil
|
||||||
|
|
||||||
private lateinit var dateUtil: DateUtil
|
private lateinit var dateUtil: DateUtil
|
||||||
|
|
||||||
private val autosensDataStore = info.nightscout.plugins.iob.iobCobCalculator.data.AutosensDataStoreObject()
|
private val autosensDataStore = AutosensDataStoreObject()
|
||||||
|
|
||||||
|
private val injector = HasAndroidInjector {
|
||||||
|
AndroidInjector {
|
||||||
|
if (it is AutosensDataObject) {
|
||||||
|
it.aapsLogger = aapsLogger
|
||||||
|
it.sp = sp
|
||||||
|
it.rh = rh
|
||||||
|
it.profileFunction = profileFunction
|
||||||
|
it.dateUtil = dateUtilMocked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
fun mock() {
|
fun mock() {
|
||||||
|
@ -1264,7 +1290,7 @@ class AutosensDataStoreTest : TestBase() {
|
||||||
Assertions.assertEquals(67.0, autosensDataStore.bucketedData!![3].value, 1.0) // Recalculated data to 30min
|
Assertions.assertEquals(67.0, autosensDataStore.bucketedData!![3].value, 1.0) // Recalculated data to 30min
|
||||||
Assertions.assertEquals(45.0, autosensDataStore.bucketedData!![5].value, 1.0) // Recalculated data to 20min
|
Assertions.assertEquals(45.0, autosensDataStore.bucketedData!![5].value, 1.0) // Recalculated data to 20min
|
||||||
|
|
||||||
// non 5min data without referenceTime set, should allign the data to the time of the last reading
|
// non 5min data without referenceTime set, should align the data to the time of the last reading
|
||||||
autosensDataStore.referenceTime = -1
|
autosensDataStore.referenceTime = -1
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
bgReadingList.add(
|
bgReadingList.add(
|
||||||
|
@ -1491,4 +1517,27 @@ class AutosensDataStoreTest : TestBase() {
|
||||||
Assertions.assertEquals(T.mins(20).msecs(), autosensDataStore.findPreviousTimeFromBucketedData(T.mins(20).msecs()))
|
Assertions.assertEquals(T.mins(20).msecs(), autosensDataStore.findPreviousTimeFromBucketedData(T.mins(20).msecs()))
|
||||||
Assertions.assertEquals(T.mins(20).msecs(), autosensDataStore.findPreviousTimeFromBucketedData(T.mins(25).msecs()))
|
Assertions.assertEquals(T.mins(20).msecs(), autosensDataStore.findPreviousTimeFromBucketedData(T.mins(25).msecs()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getLastAutosensDataTest() {
|
||||||
|
val now = 10000000L
|
||||||
|
Mockito.`when`(dateUtilMocked.now()).thenReturn(now)
|
||||||
|
val ads = AutosensDataStoreObject()
|
||||||
|
ads.storedLastAutosensResult = AutosensDataObject(injector).apply { time = now - 10 }
|
||||||
|
// empty array, return last stored
|
||||||
|
ads.autosensDataTable = LongSparseArray<AutosensData>()
|
||||||
|
Assertions.assertEquals(now - 10, ads.getLastAutosensData("test", aapsLogger, dateUtilMocked)?.time)
|
||||||
|
|
||||||
|
// data is there, return it
|
||||||
|
ads.autosensDataTable.append(now - 1, AutosensDataObject(injector).apply { time = now - 1 })
|
||||||
|
Assertions.assertEquals(now - 1, ads.getLastAutosensData("test", aapsLogger, dateUtilMocked)?.time)
|
||||||
|
// and latest value should be saved
|
||||||
|
Assertions.assertEquals(now - 1, ads.storedLastAutosensResult?.time)
|
||||||
|
|
||||||
|
// data is old, return last stored
|
||||||
|
ads.storedLastAutosensResult = AutosensDataObject(injector).apply { time = now - 1 }
|
||||||
|
ads.autosensDataTable = LongSparseArray<AutosensData>()
|
||||||
|
ads.autosensDataTable.append(now - T.mins(20).msecs(), AutosensDataObject(injector).apply { time = now - T.mins(20).msecs() })
|
||||||
|
Assertions.assertEquals(now - 1, ads.getLastAutosensData("test", aapsLogger, dateUtilMocked)?.time)
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -434,7 +434,7 @@ class WizardDialog : DaggerDialogFragment() {
|
||||||
// COB
|
// COB
|
||||||
var cob = 0.0
|
var cob = 0.0
|
||||||
if (binding.cobCheckbox.isChecked) {
|
if (binding.cobCheckbox.isChecked) {
|
||||||
val cobInfo = iobCobCalculator.getCobInfo(false, "Wizard COB")
|
val cobInfo = iobCobCalculator.getCobInfo("Wizard COB")
|
||||||
cobInfo.displayCob?.let { cob = it }
|
cobInfo.displayCob?.let { cob = it }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue