Smoothing: use smoothed values in watch and wizard

This commit is contained in:
Milos Kozak 2022-12-23 10:11:45 +01:00
parent 37510088c5
commit 9c656cb140
8 changed files with 47 additions and 20 deletions

View file

@ -23,7 +23,6 @@ import info.nightscout.interfaces.aps.Loop
import info.nightscout.interfaces.configBuilder.RunningConfiguration import info.nightscout.interfaces.configBuilder.RunningConfiguration
import info.nightscout.interfaces.iob.IobCobCalculator import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.plugin.PluginBase
import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.queue.Command import info.nightscout.interfaces.queue.Command
import info.nightscout.interfaces.queue.CommandQueue import info.nightscout.interfaces.queue.CommandQueue
@ -155,8 +154,7 @@ class KeepAliveWorker(
var shouldUploadStatus = false var shouldUploadStatus = false
if (config.NSCLIENT) return if (config.NSCLIENT) return
if (config.PUMPCONTROL) shouldUploadStatus = true if (config.PUMPCONTROL) shouldUploadStatus = true
else if (!(loop as PluginBase).isEnabled() || iobCobCalculator.ads.actualBg() == null) else if (!loop.isEnabled() || iobCobCalculator.ads.actualBg() == null) shouldUploadStatus = true
shouldUploadStatus = true
else if (dateUtil.isOlderThan(activePlugin.activeAPS.lastAPSRun, 5)) shouldUploadStatus = true else if (dateUtil.isOlderThan(activePlugin.activeAPS.lastAPSRun, 5)) shouldUploadStatus = true
if (dateUtil.isOlderThan(lastIobUpload, IOB_UPDATE_FREQUENCY_IN_MINUTES) && shouldUploadStatus) { if (dateUtil.isOlderThan(lastIobUpload, IOB_UPDATE_FREQUENCY_IN_MINUTES) && shouldUploadStatus) {
lastIobUpload = dateUtil.now() lastIobUpload = dateUtil.now()

View file

@ -15,8 +15,18 @@ interface AutosensDataStore {
var bucketedData: MutableList<InMemoryGlucoseValue>? var bucketedData: MutableList<InMemoryGlucoseValue>?
var lastUsed5minCalculation: Boolean? 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 lastDataTime(dateUtil: DateUtil): String
fun clone(): AutosensDataStore fun clone(): AutosensDataStore
fun getBgReadingsDataTableCopy(): List<GlucoseValue> fun getBgReadingsDataTableCopy(): List<GlucoseValue>

View file

@ -2,6 +2,7 @@ package info.nightscout.interfaces.utils
import info.nightscout.database.entities.GlucoseValue import info.nightscout.database.entities.GlucoseValue
import info.nightscout.interfaces.aps.AutosensDataStore 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 * Convert BG direction value to trend arrow or calculate it if not provided
@ -16,6 +17,13 @@ interface TrendCalculator {
* @return TrendArrow * @return TrendArrow
*/ */
fun getTrendArrow(glucoseValue: GlucoseValue?): GlucoseValue.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 * Provide or calculate trend from newest bucketed data
* *

View file

@ -6,10 +6,10 @@ import info.nightscout.core.extensions.valueToUnits
import info.nightscout.core.iob.round import info.nightscout.core.iob.round
import info.nightscout.core.utils.MidnightUtils import info.nightscout.core.utils.MidnightUtils
import info.nightscout.database.ValueWrapper import info.nightscout.database.ValueWrapper
import info.nightscout.database.entities.GlucoseValue
import info.nightscout.interfaces.aps.Loop import info.nightscout.interfaces.aps.Loop
import info.nightscout.interfaces.db.PersistenceLayer import info.nightscout.interfaces.db.PersistenceLayer
import info.nightscout.interfaces.iob.GlucoseStatusProvider import info.nightscout.interfaces.iob.GlucoseStatusProvider
import info.nightscout.interfaces.iob.InMemoryGlucoseValue
import info.nightscout.interfaces.iob.IobCobCalculator import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.plugin.PluginBase import info.nightscout.interfaces.plugin.PluginBase
import info.nightscout.interfaces.profile.Profile 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 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 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

View file

@ -17,6 +17,13 @@ class TrendCalculatorImpl @Inject constructor(
) : TrendCalculator { ) : TrendCalculator {
override fun getTrendArrow(glucoseValue: GlucoseValue?): GlucoseValue.TrendArrow = 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 { when {
glucoseValue?.trendArrow == null -> GlucoseValue.TrendArrow.NONE glucoseValue?.trendArrow == null -> GlucoseValue.TrendArrow.NONE
glucoseValue.trendArrow != GlucoseValue.TrendArrow.NONE -> glucoseValue.trendArrow 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) 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 toTime = glucoseValue.timestamp
val readings = repository.compatGetBgReadingsDataFromTime(toTime - T.mins(10).msecs(), toTime, false).blockingGet() val readings = repository.compatGetBgReadingsDataFromTime(toTime - T.mins(10).msecs(), toTime, false).blockingGet()

View file

@ -34,6 +34,7 @@ import info.nightscout.interfaces.aps.Loop
import info.nightscout.interfaces.constraints.Constraint import info.nightscout.interfaces.constraints.Constraint
import info.nightscout.interfaces.constraints.Constraints import info.nightscout.interfaces.constraints.Constraints
import info.nightscout.interfaces.iob.GlucoseStatusProvider import info.nightscout.interfaces.iob.GlucoseStatusProvider
import info.nightscout.interfaces.iob.InMemoryGlucoseValue
import info.nightscout.interfaces.iob.IobCobCalculator import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.logging.UserEntryLogger import info.nightscout.interfaces.logging.UserEntryLogger
import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData
@ -744,8 +745,9 @@ class DataHandlerMobile @Inject constructor(
) )
) )
// GraphData // GraphData
val startTime = System.currentTimeMillis() - (60000 * 60 * 5.5).toLong() iobCobCalculator.ads.getBucketedDataTableCopy()?.let { bucketedData ->
rxBus.send(EventMobileToWear(EventData.GraphData(ArrayList(repository.compatGetBgReadingsDataFromTime(startTime, true).blockingGet().map { getSingleBG(it) })))) rxBus.send(EventMobileToWear(EventData.GraphData(ArrayList(bucketedData.map { getSingleBG(it) }))))
}
// Treatments // Treatments
sendTreatments() sendTreatments()
// Status // Status
@ -933,7 +935,7 @@ class DataHandlerMobile @Inject constructor(
return deltaString return deltaString
} }
private fun getSingleBG(glucoseValue: GlucoseValue): EventData.SingleBg { private fun getSingleBG(glucoseValue: InMemoryGlucoseValue): EventData.SingleBg {
val glucoseStatus = glucoseStatusProvider.getGlucoseStatusData(true) val glucoseStatus = glucoseStatusProvider.getGlucoseStatusData(true)
val units = profileFunction.getUnits() val units = profileFunction.getUnits()
val lowLine = Profile.toMgdl(defaultValueHelper.determineLowLine(), units) val lowLine = Profile.toMgdl(defaultValueHelper.determineLowLine(), units)

View file

@ -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) { synchronized(dataLock) {
if (bgReadings.isNotEmpty()) bgReadings[0] bucketedData?.let { bucketedData ->
else null 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 val lastBg = lastBg() ?: return null
return if (lastBg.timestamp > System.currentTimeMillis() - T.mins(9).msecs()) lastBg else null return if (lastBg.timestamp > System.currentTimeMillis() - T.mins(9).msecs()) lastBg else null
} }

View file

@ -7,5 +7,5 @@
<string name="avg_smoothing_name">Average smoothing</string> <string name="avg_smoothing_name">Average smoothing</string>
<string name="description_avg_smoothing">"Average smoothing algorithm, newest value is not affected"</string> <string name="description_avg_smoothing">"Average smoothing algorithm, newest value is not affected"</string>
<string name="no_smoothing_name">No smoothing</string> <string name="no_smoothing_name">No smoothing</string>
<string name="description_no_smoothing">"No smoothing performed on input glucose data"</string> <string name="description_no_smoothing">"No smoothing performed on input glucose data. Use this when you already have filtered data e.g. from BYODA G6."</string>
</resources> </resources>