BgQualityCheckPlugin
This commit is contained in:
parent
6fb83d4949
commit
2b021ffafc
10 changed files with 356 additions and 32 deletions
|
@ -15,6 +15,7 @@ import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
|
|||
import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
||||
import info.nightscout.androidaps.plugins.constraints.bgQualityCheck.BgQualityCheckPlugin
|
||||
import info.nightscout.androidaps.plugins.constraints.dstHelper.DstHelperPlugin
|
||||
import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin
|
||||
import info.nightscout.androidaps.plugins.constraints.safety.SafetyPlugin
|
||||
|
@ -294,6 +295,12 @@ abstract class PluginsModule {
|
|||
@IntKey(380)
|
||||
abstract fun bindDstHelperPlugin(plugin: DstHelperPlugin): PluginBase
|
||||
|
||||
@Binds
|
||||
@AllConfigs
|
||||
@IntoMap
|
||||
@IntKey(381)
|
||||
abstract fun bindBgQualityCheckPlugin(plugin: BgQualityCheckPlugin): PluginBase
|
||||
|
||||
@Binds
|
||||
@AllConfigs
|
||||
@IntoMap
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
package info.nightscout.androidaps.plugins.constraints.bgQualityCheck
|
||||
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.interfaces.*
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventBucketedDataCreated
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
import kotlin.math.abs
|
||||
|
||||
@Singleton
|
||||
class BgQualityCheckPlugin @Inject constructor(
|
||||
injector: HasAndroidInjector,
|
||||
aapsLogger: AAPSLogger,
|
||||
rh: ResourceHelper,
|
||||
private val rxBus: RxBus,
|
||||
private val iobCobCalculator: IobCobCalculator,
|
||||
private val aapsSchedulers: AapsSchedulers,
|
||||
private val fabricPrivacy: FabricPrivacy
|
||||
) : PluginBase(
|
||||
PluginDescription()
|
||||
.mainType(PluginType.CONSTRAINTS)
|
||||
.neverVisible(true)
|
||||
.alwaysEnabled(true)
|
||||
.showInList(false)
|
||||
.pluginName(R.string.dst_plugin_name),
|
||||
aapsLogger, rh, injector
|
||||
), Constraints {
|
||||
|
||||
private var disposable: CompositeDisposable = CompositeDisposable()
|
||||
|
||||
enum class State {
|
||||
UNKNOWN,
|
||||
FIVE_MIN_DATA,
|
||||
RECALCULATED,
|
||||
DOUBLED
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
disposable += rxBus
|
||||
.toObservable(EventBucketedDataCreated::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ processBgData() }, fabricPrivacy::logException)
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
disposable.clear()
|
||||
}
|
||||
|
||||
var state: State = State.UNKNOWN
|
||||
|
||||
// Return false if BG values are doubled
|
||||
@Suppress("ReplaceGetOrSet")
|
||||
override fun isLoopInvocationAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||
if (state == State.DOUBLED)
|
||||
value.set(aapsLogger, false, "Doubled values in BGSource", this)
|
||||
return value
|
||||
}
|
||||
|
||||
fun processBgData() {
|
||||
val readings = iobCobCalculator.ads.getBgReadingsDataTableCopy()
|
||||
for (i in readings.indices)
|
||||
if (i < readings.size - 2)
|
||||
if (abs(readings[i].timestamp - readings[i + 1].timestamp) <= 1000) {
|
||||
state = State.DOUBLED
|
||||
return
|
||||
}
|
||||
if (iobCobCalculator.ads.lastUsed5minCalculation == true)
|
||||
state = State.FIVE_MIN_DATA
|
||||
else if (iobCobCalculator.ads.lastUsed5minCalculation == false)
|
||||
state = State.RECALCULATED
|
||||
else
|
||||
state = State.UNKNOWN
|
||||
}
|
||||
|
||||
fun icon(): Int =
|
||||
when (state) {
|
||||
State.UNKNOWN -> 0
|
||||
State.FIVE_MIN_DATA -> 0
|
||||
State.RECALCULATED -> R.drawable.ic_baseline_warning_24_yellow
|
||||
State.DOUBLED -> R.drawable.ic_baseline_warning_24_red
|
||||
}
|
||||
}
|
|
@ -21,11 +21,11 @@ import javax.inject.Singleton
|
|||
class DstHelperPlugin @Inject constructor(
|
||||
injector: HasAndroidInjector,
|
||||
aapsLogger: AAPSLogger,
|
||||
private var rxBus: RxBus,
|
||||
private val rxBus: RxBus,
|
||||
rh: ResourceHelper,
|
||||
private var sp: SP,
|
||||
private var activePlugin: ActivePlugin,
|
||||
private var loopPlugin: LoopPlugin
|
||||
private val sp: SP,
|
||||
private val activePlugin: ActivePlugin,
|
||||
private val loopPlugin: LoopPlugin
|
||||
) : PluginBase(PluginDescription()
|
||||
.mainType(PluginType.CONSTRAINTS)
|
||||
.neverVisible(true)
|
||||
|
@ -41,6 +41,7 @@ class DstHelperPlugin @Inject constructor(
|
|||
}
|
||||
|
||||
//Return false if time to DST change happened in the last 3 hours.
|
||||
@Suppress("ReplaceGetOrSet")
|
||||
override fun isLoopInvocationAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||
val pump = activePlugin.activePump
|
||||
if (pump.canHandleDST()) {
|
||||
|
@ -52,9 +53,9 @@ class DstHelperPlugin @Inject constructor(
|
|||
val snoozedTo: Long = sp.getLong(R.string.key_snooze_dst_in24h, 0L)
|
||||
if (snoozedTo == 0L || System.currentTimeMillis() > snoozedTo) {
|
||||
val notification = NotificationWithAction(injector, Notification.DST_IN_24H, rh.gs(R.string.dst_in_24h_warning), Notification.LOW)
|
||||
notification.action(R.string.snooze, Runnable {
|
||||
notification.action(R.string.snooze) {
|
||||
sp.putLong(R.string.key_snooze_dst_in24h, System.currentTimeMillis() + T.hours(24).msecs())
|
||||
})
|
||||
}
|
||||
rxBus.send(EventNewNotification(notification))
|
||||
}
|
||||
}
|
||||
|
@ -67,9 +68,9 @@ class DstHelperPlugin @Inject constructor(
|
|||
val snoozedTo: Long = sp.getLong(R.string.key_snooze_loopdisabled, 0L)
|
||||
if (snoozedTo == 0L || System.currentTimeMillis() > snoozedTo) {
|
||||
val notification = NotificationWithAction(injector, Notification.DST_LOOP_DISABLED, rh.gs(R.string.dst_loop_disabled_warning), Notification.LOW)
|
||||
notification.action(R.string.snooze, Runnable {
|
||||
notification.action(R.string.snooze) {
|
||||
sp.putLong(R.string.key_snooze_loopdisabled, System.currentTimeMillis() + T.hours(24).msecs())
|
||||
})
|
||||
}
|
||||
rxBus.send(EventNewNotification(notification))
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -50,6 +50,7 @@ import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
|
|||
import info.nightscout.androidaps.plugins.aps.loop.events.EventNewOpenLoopNotification
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||
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
|
||||
import info.nightscout.androidaps.plugins.general.overview.activities.QuickWizardListActivity
|
||||
|
@ -122,6 +123,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
|||
@Inject lateinit var overviewData: OverviewData
|
||||
@Inject lateinit var overviewPlugin: OverviewPlugin
|
||||
@Inject lateinit var automationPlugin: AutomationPlugin
|
||||
@Inject lateinit var bgQualityCheckPlugin: BgQualityCheckPlugin
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
|
@ -661,6 +663,15 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
|||
else binding.infoLayout.bg.paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv()
|
||||
binding.infoLayout.timeAgo.text = dateUtil.minAgo(rh, overviewData.lastBg?.timestamp)
|
||||
binding.infoLayout.timeAgoShort.text = "(" + dateUtil.minAgoShort(overviewData.lastBg?.timestamp) + ")"
|
||||
|
||||
val qualityIcon = bgQualityCheckPlugin.icon()
|
||||
if (qualityIcon != 0) {
|
||||
binding.infoLayout.bgQuality.visibility = View.VISIBLE
|
||||
binding.infoLayout.bgQuality.setImageResource(qualityIcon)
|
||||
} else {
|
||||
binding.infoLayout.bgQuality.visibility = View.GONE
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
OverviewData.Property.PROFILE -> {
|
||||
|
|
|
@ -13,11 +13,8 @@ import info.nightscout.androidaps.interfaces.PluginDescription
|
|||
import info.nightscout.androidaps.interfaces.PluginType
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import info.nightscout.androidaps.utils.XDripBroadcast
|
||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
|
@ -33,13 +30,11 @@ class RandomBgPlugin @Inject constructor(
|
|||
injector: HasAndroidInjector,
|
||||
rh: ResourceHelper,
|
||||
aapsLogger: AAPSLogger,
|
||||
private val virtualPumpPlugin: VirtualPumpPlugin,
|
||||
private val buildHelper: BuildHelper,
|
||||
private val sp: SP,
|
||||
private val dateUtil: DateUtil,
|
||||
private val repository: AppRepository,
|
||||
private val xDripBroadcast: XDripBroadcast
|
||||
) : PluginBase(PluginDescription()
|
||||
) : PluginBase(
|
||||
PluginDescription()
|
||||
.mainType(PluginType.BGSOURCE)
|
||||
.fragmentClass(BGSourceFragment::class.java.name)
|
||||
.pluginIcon(R.drawable.ic_dice)
|
||||
|
@ -58,7 +53,7 @@ class RandomBgPlugin @Inject constructor(
|
|||
const val interval = 5L // minutes
|
||||
const val min = 70 // mgdl
|
||||
const val max = 190 // mgdl
|
||||
const val period = 90.0 // minutes
|
||||
const val period = 120.0 // minutes
|
||||
}
|
||||
|
||||
init {
|
||||
|
@ -94,15 +89,18 @@ class RandomBgPlugin @Inject constructor(
|
|||
}
|
||||
|
||||
private fun handleNewData() {
|
||||
if (!isEnabled(PluginType.BGSOURCE)) return
|
||||
if (!isEnabled()) return
|
||||
|
||||
val cal = GregorianCalendar()
|
||||
val currentMinute = cal.get(Calendar.MINUTE) + (cal.get(Calendar.HOUR_OF_DAY) % 2) * 60
|
||||
val currentMinute = cal[Calendar.MINUTE] + (cal[Calendar.HOUR_OF_DAY] % 2) * 60
|
||||
val bgMgdl = min + ((max - min) + (max - min) * sin(currentMinute / period * 2 * PI)) / 2
|
||||
|
||||
cal[Calendar.MILLISECOND] = 0
|
||||
cal[Calendar.SECOND] = 0
|
||||
cal[Calendar.MINUTE] -= cal[Calendar.MINUTE] % 5
|
||||
val glucoseValues = mutableListOf<CgmSourceTransaction.TransactionGlucoseValue>()
|
||||
glucoseValues += CgmSourceTransaction.TransactionGlucoseValue(
|
||||
timestamp = dateUtil.now(),
|
||||
timestamp = cal.timeInMillis,
|
||||
value = bgMgdl,
|
||||
raw = 0.0,
|
||||
noise = null,
|
||||
|
|
5
app/src/main/res/drawable/ic_baseline_warning_24_red.xml
Normal file
5
app/src/main/res/drawable/ic_baseline_warning_24_red.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="#FF0000"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M1,21h22L12,2 1,21zM13,18h-2v-2h2v2zM13,14h-2v-4h2v4z"/>
|
||||
</vector>
|
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="#FFFF00"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M1,21h22L12,2 1,21zM13,18h-2v-2h2v2zM13,14h-2v-4h2v4z"/>
|
||||
</vector>
|
|
@ -19,6 +19,14 @@
|
|||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/bg_quality"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="Blood glucose quality icon"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/delta_large"
|
||||
|
|
|
@ -0,0 +1,196 @@
|
|||
package info.nightscout.androidaps.plugins.constraints.bgQualityCheck
|
||||
|
||||
import dagger.android.AndroidInjector
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.TestBase
|
||||
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||
import info.nightscout.androidaps.interfaces.Constraint
|
||||
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensDataStore
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import org.junit.Assert
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito
|
||||
import java.util.*
|
||||
|
||||
class BgQualityCheckPluginTest : TestBase() {
|
||||
|
||||
@Mock lateinit var rh: ResourceHelper
|
||||
@Mock lateinit var iobCobCalculator: IobCobCalculator
|
||||
@Mock lateinit var fabricPrivacy: FabricPrivacy
|
||||
|
||||
private lateinit var plugin: BgQualityCheckPlugin
|
||||
|
||||
val injector = HasAndroidInjector { AndroidInjector { } }
|
||||
private val autosensDataStore = AutosensDataStore()
|
||||
|
||||
@Before
|
||||
fun mock() {
|
||||
plugin = BgQualityCheckPlugin(injector, aapsLogger, rh, RxBus(aapsSchedulers, aapsLogger), iobCobCalculator, aapsSchedulers, fabricPrivacy)
|
||||
Mockito.`when`(iobCobCalculator.ads).thenReturn(autosensDataStore)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun runTest() {
|
||||
autosensDataStore.lastUsed5minCalculation = null
|
||||
plugin.processBgData()
|
||||
Assert.assertEquals(BgQualityCheckPlugin.State.UNKNOWN, plugin.state)
|
||||
Assert.assertEquals(0, plugin.icon())
|
||||
autosensDataStore.lastUsed5minCalculation = true
|
||||
plugin.processBgData()
|
||||
Assert.assertEquals(BgQualityCheckPlugin.State.FIVE_MIN_DATA, plugin.state)
|
||||
Assert.assertEquals(0, plugin.icon())
|
||||
autosensDataStore.lastUsed5minCalculation = false
|
||||
plugin.processBgData()
|
||||
Assert.assertEquals(BgQualityCheckPlugin.State.RECALCULATED, plugin.state)
|
||||
Assert.assertEquals(R.drawable.ic_baseline_warning_24_yellow, plugin.icon())
|
||||
|
||||
val superData: MutableList<GlucoseValue> = ArrayList()
|
||||
superData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
superData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
superData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
superData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
autosensDataStore.bgReadings = superData
|
||||
|
||||
autosensDataStore.lastUsed5minCalculation = true
|
||||
plugin.processBgData()
|
||||
Assert.assertEquals(BgQualityCheckPlugin.State.FIVE_MIN_DATA, plugin.state)
|
||||
autosensDataStore.lastUsed5minCalculation = false
|
||||
plugin.processBgData()
|
||||
Assert.assertEquals(BgQualityCheckPlugin.State.RECALCULATED, plugin.state)
|
||||
|
||||
val duplicatedData: MutableList<GlucoseValue> = ArrayList()
|
||||
duplicatedData.add(
|
||||
GlucoseValue(
|
||||
raw = 0.0,
|
||||
noise = 0.0,
|
||||
value = 100.0,
|
||||
timestamp = T.mins(20).msecs(),
|
||||
sourceSensor = GlucoseValue.SourceSensor.UNKNOWN,
|
||||
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||
)
|
||||
)
|
||||
duplicatedData.add(
|
||||
GlucoseValue(
|
||||
raw = 0.0,
|
||||
noise = 0.0,
|
||||
value = 100.0,
|
||||
timestamp = T.mins(20).msecs() + 1,
|
||||
sourceSensor = GlucoseValue.SourceSensor.UNKNOWN,
|
||||
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||
)
|
||||
)
|
||||
duplicatedData.add(
|
||||
GlucoseValue(
|
||||
raw = 0.0,
|
||||
noise = 0.0,
|
||||
value = 100.0,
|
||||
timestamp = T.mins(10).msecs(),
|
||||
sourceSensor = GlucoseValue.SourceSensor.UNKNOWN,
|
||||
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||
)
|
||||
)
|
||||
duplicatedData.add(
|
||||
GlucoseValue(
|
||||
raw = 0.0,
|
||||
noise = 0.0,
|
||||
value = 100.0,
|
||||
timestamp = T.mins(15).msecs(),
|
||||
sourceSensor = GlucoseValue.SourceSensor.UNKNOWN,
|
||||
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||
)
|
||||
)
|
||||
duplicatedData.add(
|
||||
GlucoseValue(
|
||||
raw = 0.0,
|
||||
noise = 0.0,
|
||||
value = 100.0,
|
||||
timestamp = T.mins(5).msecs(),
|
||||
sourceSensor = GlucoseValue.SourceSensor.UNKNOWN,
|
||||
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||
)
|
||||
)
|
||||
autosensDataStore.bgReadings = duplicatedData
|
||||
|
||||
autosensDataStore.lastUsed5minCalculation = true
|
||||
plugin.processBgData()
|
||||
Assert.assertEquals(BgQualityCheckPlugin.State.DOUBLED, plugin.state)
|
||||
Assert.assertEquals(R.drawable.ic_baseline_warning_24_red, plugin.icon())
|
||||
|
||||
val identicalData: MutableList<GlucoseValue> = ArrayList()
|
||||
identicalData.add(
|
||||
GlucoseValue(
|
||||
raw = 0.0,
|
||||
noise = 0.0,
|
||||
value = 100.0,
|
||||
timestamp = T.mins(20).msecs(),
|
||||
sourceSensor = GlucoseValue.SourceSensor.UNKNOWN,
|
||||
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||
)
|
||||
)
|
||||
identicalData.add(
|
||||
GlucoseValue(
|
||||
raw = 0.0,
|
||||
noise = 0.0,
|
||||
value = 100.0,
|
||||
timestamp = T.mins(20).msecs(),
|
||||
sourceSensor = GlucoseValue.SourceSensor.UNKNOWN,
|
||||
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||
)
|
||||
)
|
||||
identicalData.add(
|
||||
GlucoseValue(
|
||||
raw = 0.0,
|
||||
noise = 0.0,
|
||||
value = 100.0,
|
||||
timestamp = T.mins(10).msecs(),
|
||||
sourceSensor = GlucoseValue.SourceSensor.UNKNOWN,
|
||||
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||
)
|
||||
)
|
||||
identicalData.add(
|
||||
GlucoseValue(
|
||||
raw = 0.0,
|
||||
noise = 0.0,
|
||||
value = 100.0,
|
||||
timestamp = T.mins(15).msecs(),
|
||||
sourceSensor = GlucoseValue.SourceSensor.UNKNOWN,
|
||||
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||
)
|
||||
)
|
||||
identicalData.add(
|
||||
GlucoseValue(
|
||||
raw = 0.0,
|
||||
noise = 0.0,
|
||||
value = 100.0,
|
||||
timestamp = T.mins(5).msecs(),
|
||||
sourceSensor = GlucoseValue.SourceSensor.UNKNOWN,
|
||||
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||
)
|
||||
)
|
||||
autosensDataStore.bgReadings = identicalData
|
||||
|
||||
autosensDataStore.lastUsed5minCalculation = false
|
||||
plugin.processBgData()
|
||||
Assert.assertEquals(BgQualityCheckPlugin.State.DOUBLED, plugin.state)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isLoopInvocationAllowedTest() {
|
||||
plugin.state = BgQualityCheckPlugin.State.UNKNOWN
|
||||
Assert.assertEquals(true, plugin.isLoopInvocationAllowed(Constraint(true)).value())
|
||||
plugin.state = BgQualityCheckPlugin.State.FIVE_MIN_DATA
|
||||
Assert.assertEquals(true, plugin.isLoopInvocationAllowed(Constraint(true)).value())
|
||||
plugin.state = BgQualityCheckPlugin.State.RECALCULATED
|
||||
Assert.assertEquals(true, plugin.isLoopInvocationAllowed(Constraint(true)).value())
|
||||
plugin.state = BgQualityCheckPlugin.State.DOUBLED
|
||||
Assert.assertEquals(false, plugin.isLoopInvocationAllowed(Constraint(true)).value())
|
||||
}
|
||||
|
||||
}
|
|
@ -19,7 +19,7 @@ import kotlin.math.roundToLong
|
|||
class AutosensDataStore {
|
||||
|
||||
private val dataLock = Any()
|
||||
private var lastUsed5minCalculation: Boolean? = null // true if used 5min bucketed data
|
||||
var lastUsed5minCalculation: Boolean? = null // true if used 5min bucketed data
|
||||
|
||||
// we need to make sure that bucketed_data will always have the same timestamp for correct use of cached values
|
||||
// once referenceTime != null all bucketed data should be (x * 5min) from referenceTime
|
||||
|
|
Loading…
Reference in a new issue