From 9c656cb140b8f5275d37af65f57fba155b4155f4 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 23 Dec 2022 10:11:45 +0100 Subject: [PATCH] Smoothing: use smoothed values in watch and wizard --- .../androidaps/receivers/KeepAliveWorker.kt | 4 +--- .../interfaces/aps/AutosensDataStore.kt | 14 ++++++++++++-- .../interfaces/utils/TrendCalculator.kt | 8 ++++++++ .../nightscout/core/wizard/QuickWizardEntry.kt | 4 ++-- .../implementation/TrendCalculatorImpl.kt | 9 ++++++++- .../wear/wearintegration/DataHandlerMobile.kt | 8 +++++--- .../data/AutosensDataStoreObject.kt | 18 ++++++++++-------- .../smoothing/src/main/res/values/strings.xml | 2 +- 8 files changed, 47 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveWorker.kt b/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveWorker.kt index 539eb6f7d1..b4c84e5193 100644 --- a/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveWorker.kt +++ b/app/src/main/java/info/nightscout/androidaps/receivers/KeepAliveWorker.kt @@ -23,7 +23,6 @@ import info.nightscout.interfaces.aps.Loop import info.nightscout.interfaces.configBuilder.RunningConfiguration import info.nightscout.interfaces.iob.IobCobCalculator import info.nightscout.interfaces.plugin.ActivePlugin -import info.nightscout.interfaces.plugin.PluginBase import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.queue.Command import info.nightscout.interfaces.queue.CommandQueue @@ -155,8 +154,7 @@ class KeepAliveWorker( var shouldUploadStatus = false if (config.NSCLIENT) return if (config.PUMPCONTROL) shouldUploadStatus = true - else if (!(loop as PluginBase).isEnabled() || iobCobCalculator.ads.actualBg() == null) - shouldUploadStatus = true + else if (!loop.isEnabled() || iobCobCalculator.ads.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() diff --git a/core/interfaces/src/main/java/info/nightscout/interfaces/aps/AutosensDataStore.kt b/core/interfaces/src/main/java/info/nightscout/interfaces/aps/AutosensDataStore.kt index 3e88091c12..d38a7aef20 100644 --- a/core/interfaces/src/main/java/info/nightscout/interfaces/aps/AutosensDataStore.kt +++ b/core/interfaces/src/main/java/info/nightscout/interfaces/aps/AutosensDataStore.kt @@ -15,8 +15,18 @@ interface AutosensDataStore { var bucketedData: MutableList? var lastUsed5minCalculation: Boolean? - fun lastBg(): GlucoseValue? - fun actualBg(): GlucoseValue? + /** + * Return last valid (>39) InMemoryGlucoseValue from bucketed data or null if db is empty + * + * @return InMemoryGlucoseValue or null + */ + fun lastBg(): InMemoryGlucoseValue? + /** + * Provide last bucketed InMemoryGlucoseValue or null if none exists within the last 9 minutes + * + * @return InMemoryGlucoseValue or null + */ + fun actualBg(): InMemoryGlucoseValue? fun lastDataTime(dateUtil: DateUtil): String fun clone(): AutosensDataStore fun getBgReadingsDataTableCopy(): List diff --git a/core/interfaces/src/main/java/info/nightscout/interfaces/utils/TrendCalculator.kt b/core/interfaces/src/main/java/info/nightscout/interfaces/utils/TrendCalculator.kt index 6cc7e4a729..13e753b8af 100644 --- a/core/interfaces/src/main/java/info/nightscout/interfaces/utils/TrendCalculator.kt +++ b/core/interfaces/src/main/java/info/nightscout/interfaces/utils/TrendCalculator.kt @@ -2,6 +2,7 @@ package info.nightscout.interfaces.utils import info.nightscout.database.entities.GlucoseValue import info.nightscout.interfaces.aps.AutosensDataStore +import info.nightscout.interfaces.iob.InMemoryGlucoseValue /** * Convert BG direction value to trend arrow or calculate it if not provided @@ -16,6 +17,13 @@ interface TrendCalculator { * @return TrendArrow */ fun getTrendArrow(glucoseValue: GlucoseValue?): GlucoseValue.TrendArrow + /** + * Provide or calculate trend + * + * @param glucoseValue BG + * @return TrendArrow + */ + fun getTrendArrow(glucoseValue: InMemoryGlucoseValue?): GlucoseValue.TrendArrow /** * Provide or calculate trend from newest bucketed data * diff --git a/core/main/src/main/java/info/nightscout/core/wizard/QuickWizardEntry.kt b/core/main/src/main/java/info/nightscout/core/wizard/QuickWizardEntry.kt index 1a489bd7af..0f46f6f50c 100644 --- a/core/main/src/main/java/info/nightscout/core/wizard/QuickWizardEntry.kt +++ b/core/main/src/main/java/info/nightscout/core/wizard/QuickWizardEntry.kt @@ -6,10 +6,10 @@ import info.nightscout.core.extensions.valueToUnits import info.nightscout.core.iob.round import info.nightscout.core.utils.MidnightUtils import info.nightscout.database.ValueWrapper -import info.nightscout.database.entities.GlucoseValue import info.nightscout.interfaces.aps.Loop import info.nightscout.interfaces.db.PersistenceLayer import info.nightscout.interfaces.iob.GlucoseStatusProvider +import info.nightscout.interfaces.iob.InMemoryGlucoseValue import info.nightscout.interfaces.iob.IobCobCalculator import info.nightscout.interfaces.plugin.PluginBase import info.nightscout.interfaces.profile.Profile @@ -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 doCalc(profile: Profile, profileName: String, lastBG: GlucoseValue, _synchronized: Boolean): BolusWizard { + fun doCalc(profile: Profile, profileName: String, lastBG: InMemoryGlucoseValue, _synchronized: Boolean): BolusWizard { val dbRecord = persistenceLayer.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet() val tempTarget = if (dbRecord is ValueWrapper.Existing) dbRecord.value else null //BG diff --git a/implementation/src/main/java/info/nightscout/implementation/TrendCalculatorImpl.kt b/implementation/src/main/java/info/nightscout/implementation/TrendCalculatorImpl.kt index 804434188f..ead7b57577 100644 --- a/implementation/src/main/java/info/nightscout/implementation/TrendCalculatorImpl.kt +++ b/implementation/src/main/java/info/nightscout/implementation/TrendCalculatorImpl.kt @@ -17,6 +17,13 @@ class TrendCalculatorImpl @Inject constructor( ) : TrendCalculator { override fun getTrendArrow(glucoseValue: GlucoseValue?): GlucoseValue.TrendArrow = + when { + glucoseValue?.trendArrow == null -> GlucoseValue.TrendArrow.NONE + glucoseValue.trendArrow != GlucoseValue.TrendArrow.NONE -> glucoseValue.trendArrow + else -> calculateDirection(InMemoryGlucoseValue(glucoseValue)) + } + + override fun getTrendArrow(glucoseValue: InMemoryGlucoseValue?): GlucoseValue.TrendArrow = when { glucoseValue?.trendArrow == null -> GlucoseValue.TrendArrow.NONE glucoseValue.trendArrow != GlucoseValue.TrendArrow.NONE -> glucoseValue.trendArrow @@ -36,7 +43,7 @@ class TrendCalculatorImpl @Inject constructor( else -> rh.gs(info.nightscout.core.ui.R.string.a11y_arrow_unknown) } - private fun calculateDirection(glucoseValue: GlucoseValue): GlucoseValue.TrendArrow { + private fun calculateDirection(glucoseValue: InMemoryGlucoseValue): GlucoseValue.TrendArrow { val toTime = glucoseValue.timestamp val readings = repository.compatGetBgReadingsDataFromTime(toTime - T.mins(10).msecs(), toTime, false).blockingGet() diff --git a/plugins/main/src/main/java/info/nightscout/plugins/general/wear/wearintegration/DataHandlerMobile.kt b/plugins/main/src/main/java/info/nightscout/plugins/general/wear/wearintegration/DataHandlerMobile.kt index 8efbf91571..889e4bd5ed 100644 --- a/plugins/main/src/main/java/info/nightscout/plugins/general/wear/wearintegration/DataHandlerMobile.kt +++ b/plugins/main/src/main/java/info/nightscout/plugins/general/wear/wearintegration/DataHandlerMobile.kt @@ -34,6 +34,7 @@ import info.nightscout.interfaces.aps.Loop import info.nightscout.interfaces.constraints.Constraint import info.nightscout.interfaces.constraints.Constraints import info.nightscout.interfaces.iob.GlucoseStatusProvider +import info.nightscout.interfaces.iob.InMemoryGlucoseValue import info.nightscout.interfaces.iob.IobCobCalculator import info.nightscout.interfaces.logging.UserEntryLogger import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData @@ -744,8 +745,9 @@ class DataHandlerMobile @Inject constructor( ) ) // GraphData - val startTime = System.currentTimeMillis() - (60000 * 60 * 5.5).toLong() - rxBus.send(EventMobileToWear(EventData.GraphData(ArrayList(repository.compatGetBgReadingsDataFromTime(startTime, true).blockingGet().map { getSingleBG(it) })))) + iobCobCalculator.ads.getBucketedDataTableCopy()?.let { bucketedData -> + rxBus.send(EventMobileToWear(EventData.GraphData(ArrayList(bucketedData.map { getSingleBG(it) })))) + } // Treatments sendTreatments() // Status @@ -933,7 +935,7 @@ class DataHandlerMobile @Inject constructor( return deltaString } - private fun getSingleBG(glucoseValue: GlucoseValue): EventData.SingleBg { + private fun getSingleBG(glucoseValue: InMemoryGlucoseValue): EventData.SingleBg { val glucoseStatus = glucoseStatusProvider.getGlucoseStatusData(true) val units = profileFunction.getUnits() val lowLine = Profile.toMgdl(defaultValueHelper.determineLowLine(), units) diff --git a/plugins/main/src/main/java/info/nightscout/plugins/iob/iobCobCalculator/data/AutosensDataStoreObject.kt b/plugins/main/src/main/java/info/nightscout/plugins/iob/iobCobCalculator/data/AutosensDataStoreObject.kt index 023be6c1c9..a31c28441e 100644 --- a/plugins/main/src/main/java/info/nightscout/plugins/iob/iobCobCalculator/data/AutosensDataStoreObject.kt +++ b/plugins/main/src/main/java/info/nightscout/plugins/iob/iobCobCalculator/data/AutosensDataStoreObject.kt @@ -71,22 +71,24 @@ class AutosensDataStoreObject : AutosensDataStore { } /** - * Return last valid (>39) GlucoseValue from database or null if db is empty + * Return last valid (>39) InMemoryGlucoseValue from bucketed data or null if db is empty * - * @return GlucoseValue or null + * @return InMemoryGlucoseValue or null */ - override fun lastBg(): GlucoseValue? = + override fun lastBg(): InMemoryGlucoseValue? = synchronized(dataLock) { - if (bgReadings.isNotEmpty()) bgReadings[0] - else null + bucketedData?.let { bucketedData -> + if (bucketedData.isNotEmpty()) bucketedData[0] + else null + } } /** - * Provide last GlucoseValue or null if none exists within the last 9 minutes + * Provide last bucketed InMemoryGlucoseValue or null if none exists within the last 9 minutes * - * @return GlucoseValue or null + * @return InMemoryGlucoseValue or null */ - override fun actualBg(): GlucoseValue? { + override fun actualBg(): InMemoryGlucoseValue? { val lastBg = lastBg() ?: return null return if (lastBg.timestamp > System.currentTimeMillis() - T.mins(9).msecs()) lastBg else null } diff --git a/plugins/smoothing/src/main/res/values/strings.xml b/plugins/smoothing/src/main/res/values/strings.xml index 474ec0d7e9..19b45a22bd 100644 --- a/plugins/smoothing/src/main/res/values/strings.xml +++ b/plugins/smoothing/src/main/res/values/strings.xml @@ -7,5 +7,5 @@ Average smoothing "Average smoothing algorithm, newest value is not affected" No smoothing - "No smoothing performed on input glucose data" + "No smoothing performed on input glucose data. Use this when you already have filtered data e.g. from BYODA G6." \ No newline at end of file