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

View file

@ -15,8 +15,18 @@ interface AutosensDataStore {
var bucketedData: MutableList<InMemoryGlucoseValue>?
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<GlucoseValue>

View file

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

View file

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

View file

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

View file

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

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

View file

@ -7,5 +7,5 @@
<string name="avg_smoothing_name">Average smoothing</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="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>