TrendCalculator -> implementation module

This commit is contained in:
Milos Kozak 2022-11-03 23:07:58 +01:00
parent da77dec5c9
commit 3d3623dc58
6 changed files with 99 additions and 69 deletions

View file

@ -32,6 +32,7 @@ import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.interfaces.SmsCommunicator
import info.nightscout.androidaps.interfaces.TrendCalculator
import info.nightscout.androidaps.interfaces.XDripBroadcast
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.bus.RxBus
@ -60,6 +61,7 @@ import info.nightscout.implementation.AndroidPermissionImpl
import info.nightscout.implementation.BolusTimerImpl
import info.nightscout.implementation.CarbTimerImpl
import info.nightscout.implementation.LocalAlertUtilsImpl
import info.nightscout.implementation.TrendCalculatorImpl
import info.nightscout.implementation.XDripBroadcastImpl
import info.nightscout.implementation.constraints.ConstraintsImpl
import info.nightscout.implementation.queue.CommandQueueImplementation
@ -143,6 +145,7 @@ open class AppModule {
@Binds fun bindAndroidPermissionInterface(androidPermission: AndroidPermissionImpl): AndroidPermission
@Binds fun bindLocalAlertUtilsInterface(localAlertUtils: LocalAlertUtilsImpl): LocalAlertUtils
@Binds fun bindActivityNamesInterface(activityNames: ActivityNamesImpl): ActivityNames
@Binds fun bindTrendCalculatorInterface(trendCalculator: TrendCalculatorImpl): TrendCalculator
}
}

View file

@ -62,6 +62,7 @@ import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.interfaces.CommandQueue
import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.interfaces.Constraints
import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.interfaces.IobCobCalculator
import info.nightscout.androidaps.interfaces.Loop
@ -69,11 +70,11 @@ import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.interfaces.TrendCalculator
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.aps.loop.events.EventNewOpenLoopNotification
import info.nightscout.androidaps.plugins.aps.openAPSSMB.DetermineBasalResultSMB
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.interfaces.Constraints
import info.nightscout.androidaps.plugins.constraints.bgQualityCheck.BgQualityCheckPlugin
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus
@ -96,7 +97,6 @@ import info.nightscout.androidaps.utils.DefaultValueHelper
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.JsonHelper
import info.nightscout.androidaps.utils.ToastUtils
import info.nightscout.androidaps.utils.TrendCalculator
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.protection.ProtectionCheck
import info.nightscout.androidaps.utils.rx.AapsSchedulers

View file

@ -0,0 +1,26 @@
package info.nightscout.androidaps.interfaces
import info.nightscout.androidaps.database.entities.GlucoseValue
/**
* Convert BG direction value to trend arrow or calculate it if not provided
* If calculation is necessary more values are loaded from DB
*/
interface TrendCalculator {
/**
* Provide or calculate trend
*
* @param glucoseValue BG
* @return TrendArrow
*/
fun getTrendArrow(glucoseValue: GlucoseValue?): GlucoseValue.TrendArrow
/**
* Provide or calculate trend
*
* @param glucoseValue BG
* @return string description of TrendArrow
*/
fun getTrendDescription(glucoseValue: GlucoseValue?): String
}

View file

@ -1,65 +0,0 @@
package info.nightscout.androidaps.utils
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.database.entities.GlucoseValue.TrendArrow.*
import info.nightscout.androidaps.interfaces.ResourceHelper
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class TrendCalculator @Inject constructor(
private val repository: AppRepository,
private val rh: ResourceHelper
) {
fun getTrendArrow(glucoseValue: GlucoseValue?): GlucoseValue.TrendArrow =
when {
glucoseValue?.trendArrow == null -> NONE
glucoseValue.trendArrow != NONE -> glucoseValue.trendArrow
else -> calculateDirection(glucoseValue)
}
fun getTrendDescription(glucoseValue: GlucoseValue?): String =
when (getTrendArrow(glucoseValue)) {
DOUBLE_DOWN -> rh.gs(R.string.a11y_arrow_double_down)
SINGLE_DOWN -> rh.gs(R.string.a11y_arrow_single_down)
FORTY_FIVE_DOWN -> rh.gs(R.string.a11y_arrow_forty_five_down)
FLAT -> rh.gs(R.string.a11y_arrow_flat)
FORTY_FIVE_UP -> rh.gs(R.string.a11y_arrow_forty_five_up)
SINGLE_UP -> rh.gs(R.string.a11y_arrow_single_up)
DOUBLE_UP -> rh.gs(R.string.a11y_arrow_double_up)
NONE -> rh.gs(R.string.a11y_arrow_none)
else -> rh.gs(R.string.a11y_arrow_unknown)
}
private fun calculateDirection(glucoseValue: GlucoseValue): GlucoseValue.TrendArrow {
val toTime = glucoseValue.timestamp
val readings = repository.compatGetBgReadingsDataFromTime(toTime - T.mins(10).msecs(), toTime, false).blockingGet()
if (readings.size < 2)
return NONE
val current = readings[0]
val previous = readings[1]
// Avoid division by 0
val slope =
if (current.timestamp == previous.timestamp) 0.0
else (previous.value - current.value) / (previous.timestamp - current.timestamp)
val slopeByMinute = slope * 60000
return when {
slopeByMinute <= -3.5 -> DOUBLE_DOWN
slopeByMinute <= -2 -> SINGLE_DOWN
slopeByMinute <= -1 -> FORTY_FIVE_DOWN
slopeByMinute <= 1 -> FLAT
slopeByMinute <= 2 -> FORTY_FIVE_UP
slopeByMinute <= 3.5 -> SINGLE_UP
slopeByMinute <= 40 -> DOUBLE_UP
else -> NONE
}
}
}

View file

@ -0,0 +1,66 @@
package info.nightscout.implementation
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.interfaces.TrendCalculator
import info.nightscout.androidaps.utils.T
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class TrendCalculatorImpl @Inject constructor(
private val repository: AppRepository,
private val rh: ResourceHelper
) : TrendCalculator {
override fun getTrendArrow(glucoseValue: GlucoseValue?): GlucoseValue.TrendArrow =
when {
glucoseValue?.trendArrow == null -> GlucoseValue.TrendArrow.NONE
glucoseValue.trendArrow != GlucoseValue.TrendArrow.NONE -> glucoseValue.trendArrow
else -> calculateDirection(glucoseValue)
}
override fun getTrendDescription(glucoseValue: GlucoseValue?): String =
when (getTrendArrow(glucoseValue)) {
GlucoseValue.TrendArrow.DOUBLE_DOWN -> rh.gs(R.string.a11y_arrow_double_down)
GlucoseValue.TrendArrow.SINGLE_DOWN -> rh.gs(R.string.a11y_arrow_single_down)
GlucoseValue.TrendArrow.FORTY_FIVE_DOWN -> rh.gs(R.string.a11y_arrow_forty_five_down)
GlucoseValue.TrendArrow.FLAT -> rh.gs(R.string.a11y_arrow_flat)
GlucoseValue.TrendArrow.FORTY_FIVE_UP -> rh.gs(R.string.a11y_arrow_forty_five_up)
GlucoseValue.TrendArrow.SINGLE_UP -> rh.gs(R.string.a11y_arrow_single_up)
GlucoseValue.TrendArrow.DOUBLE_UP -> rh.gs(R.string.a11y_arrow_double_up)
GlucoseValue.TrendArrow.NONE -> rh.gs(R.string.a11y_arrow_none)
else -> rh.gs(R.string.a11y_arrow_unknown)
}
private fun calculateDirection(glucoseValue: GlucoseValue): GlucoseValue.TrendArrow {
val toTime = glucoseValue.timestamp
val readings = repository.compatGetBgReadingsDataFromTime(toTime - T.mins(10).msecs(), toTime, false).blockingGet()
if (readings.size < 2)
return GlucoseValue.TrendArrow.NONE
val current = readings[0]
val previous = readings[1]
// Avoid division by 0
val slope =
if (current.timestamp == previous.timestamp) 0.0
else (previous.value - current.value) / (previous.timestamp - current.timestamp)
val slopeByMinute = slope * 60000
return when {
slopeByMinute <= -3.5 -> GlucoseValue.TrendArrow.DOUBLE_DOWN
slopeByMinute <= -2 -> GlucoseValue.TrendArrow.SINGLE_DOWN
slopeByMinute <= -1 -> GlucoseValue.TrendArrow.FORTY_FIVE_DOWN
slopeByMinute <= 1 -> GlucoseValue.TrendArrow.FLAT
slopeByMinute <= 2 -> GlucoseValue.TrendArrow.FORTY_FIVE_UP
slopeByMinute <= 3.5 -> GlucoseValue.TrendArrow.SINGLE_UP
slopeByMinute <= 40 -> GlucoseValue.TrendArrow.DOUBLE_UP
else -> GlucoseValue.TrendArrow.NONE
}
}
}

View file

@ -22,18 +22,18 @@ import info.nightscout.androidaps.extensions.valueToUnitsString
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.ActivityNames
import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.Constraints
import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.interfaces.IobCobCalculator
import info.nightscout.androidaps.interfaces.Loop
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.interfaces.TrendCalculator
import info.nightscout.androidaps.interfaces.VariableSensitivityResult
import info.nightscout.androidaps.interfaces.Constraints
import info.nightscout.androidaps.plugins.general.overview.OverviewData
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.TrendCalculator
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import info.nightscout.shared.sharedPreferences.SP