GlucoseStatusProviderImpl

This commit is contained in:
Milos Kozak 2022-12-07 19:55:08 +01:00
parent db0f440bb2
commit be647d8b5b
41 changed files with 2022 additions and 1001 deletions

View file

@ -10,9 +10,9 @@ import info.nightscout.androidaps.insight.database.InsightDatabase
import info.nightscout.androidaps.insight.database.InsightDatabaseDao
import info.nightscout.androidaps.insight.database.InsightDbHelper
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
import info.nightscout.core.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.database.impl.AppRepository
import info.nightscout.implementation.constraints.ConstraintsImpl
import info.nightscout.implementation.iob.GlucoseStatusProviderImpl
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
import info.nightscout.interfaces.constraints.Constraint
import info.nightscout.interfaces.constraints.Constraints
@ -45,11 +45,10 @@ import info.nightscout.pump.dana.DanaPump
import info.nightscout.pump.dana.R
import info.nightscout.pump.dana.database.DanaHistoryDatabase
import info.nightscout.shared.sharedPreferences.SP
import org.junit.Assert
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.`when`
/**
@ -134,15 +133,15 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
// RS constructor
`when`(sp.getString(R.string.key_danars_name, "")).thenReturn("")
`when`(sp.getString(info.nightscout.pump.dana.R.string.key_danars_address, "")).thenReturn("")
`when`(sp.getString(R.string.key_danars_address, "")).thenReturn("")
// R
`when`(sp.getString(info.nightscout.pump.dana.R.string.key_danar_bt_name, "")).thenReturn("")
`when`(sp.getString(R.string.key_danar_bt_name, "")).thenReturn("")
//SafetyPlugin
`when`(activePlugin.activePump).thenReturn(virtualPumpPlugin)
constraintChecker = ConstraintsImpl(activePlugin)
val glucoseStatusProvider = GlucoseStatusProvider(aapsLogger = aapsLogger, iobCobCalculator = iobCobCalculator, dateUtil = dateUtil)
val glucoseStatusProvider = GlucoseStatusProviderImpl(aapsLogger = aapsLogger, iobCobCalculator = iobCobCalculator, dateUtil = dateUtil)
hardLimits = HardLimitsMock(sp, rh)
insightDbHelper = InsightDbHelper(insightDatabaseDao)
@ -265,9 +264,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
comboPlugin.setPluginEnabled(PluginType.PUMP, true)
comboPlugin.setValidBasalRateProfileSelectedOnPump(false)
val c = constraintChecker.isLoopInvocationAllowed()
Assert.assertEquals(true, c.reasonList.size == 2) // Combo & Objectives
Assert.assertEquals(true, c.mostLimitedReasonList.size == 2) // Combo & Objectives
Assert.assertEquals(java.lang.Boolean.FALSE, c.value())
Assertions.assertEquals(true, c.reasonList.size == 2) // Combo & Objectives
Assertions.assertEquals(true, c.mostLimitedReasonList.size == 2) // Combo & Objectives
Assertions.assertEquals(java.lang.Boolean.FALSE, c.value())
}
// Safety & Objectives
@ -278,13 +277,13 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
objectivesPlugin.objectives[Objectives.MAXIOB_ZERO_CL_OBJECTIVE].startedOn = 0
var c: Constraint<Boolean> = constraintChecker.isClosedLoopAllowed()
aapsLogger.debug("Reason list: " + c.reasonList.toString())
// Assert.assertTrue(c.reasonList[0].toString().contains("Closed loop is disabled")) // Safety & Objectives
Assert.assertEquals(false, c.value())
// Assertions.assertTrue(c.reasonList[0].toString().contains("Closed loop is disabled")) // Safety & Objectives
Assertions.assertEquals(false, c.value())
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")).thenReturn("open")
c = constraintChecker.isClosedLoopAllowed()
Assert.assertTrue(c.reasonList[0].contains("Closed loop mode disabled in preferences")) // Safety & Objectives
// Assert.assertEquals(3, c.reasonList.size) // 2x Safety & Objectives
Assert.assertEquals(false, c.value())
Assertions.assertTrue(c.reasonList[0].contains("Closed loop mode disabled in preferences")) // Safety & Objectives
// Assertions.assertEquals(3, c.reasonList.size) // 2x Safety & Objectives
Assertions.assertEquals(false, c.value())
}
// Safety & Objectives
@ -294,9 +293,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
objectivesPlugin.objectives[Objectives.AUTOSENS_OBJECTIVE].startedOn = 0
`when`(sp.getBoolean(info.nightscout.plugins.aps.R.string.key_openapsama_use_autosens, false)).thenReturn(false)
val c = constraintChecker.isAutosensModeEnabled()
Assert.assertEquals(true, c.reasonList.size == 2) // Safety & Objectives
Assert.assertEquals(true, c.mostLimitedReasonList.size == 2) // Safety & Objectives
Assert.assertEquals(java.lang.Boolean.FALSE, c.value())
Assertions.assertEquals(true, c.reasonList.size == 2) // Safety & Objectives
Assertions.assertEquals(true, c.mostLimitedReasonList.size == 2) // Safety & Objectives
Assertions.assertEquals(java.lang.Boolean.FALSE, c.value())
}
// Safety
@ -304,9 +303,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
fun isAdvancedFilteringEnabledTest() {
`when`(activePlugin.activeBgSource).thenReturn(glimpPlugin)
val c = constraintChecker.isAdvancedFilteringEnabled()
Assert.assertEquals(true, c.reasonList.size == 1) // Safety
Assert.assertEquals(true, c.mostLimitedReasonList.size == 1) // Safety
Assert.assertEquals(false, c.value())
Assertions.assertEquals(true, c.reasonList.size == 1) // Safety
Assertions.assertEquals(true, c.mostLimitedReasonList.size == 1) // Safety
Assertions.assertEquals(false, c.value())
}
// SMB should limit
@ -314,7 +313,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
fun isSuperBolusEnabledTest() {
openAPSSMBPlugin.setPluginEnabled(PluginType.APS, true)
val c = constraintChecker.isSuperBolusEnabled()
Assert.assertEquals(java.lang.Boolean.FALSE, c.value()) // SMB should limit
Assertions.assertEquals(java.lang.Boolean.FALSE, c.value()) // SMB should limit
}
// Safety & Objectives
@ -326,9 +325,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")).thenReturn("open")
// `when`(constraintChecker.isClosedLoopAllowed()).thenReturn(Constraint(true))
val c = constraintChecker.isSMBModeEnabled()
Assert.assertEquals(true, c.reasonList.size == 3) // 2x Safety & Objectives
Assert.assertEquals(true, c.mostLimitedReasonList.size == 3) // 2x Safety & Objectives
Assert.assertEquals(false, c.value())
Assertions.assertEquals(true, c.reasonList.size == 3) // 2x Safety & Objectives
Assertions.assertEquals(true, c.mostLimitedReasonList.size == 3) // 2x Safety & Objectives
Assertions.assertEquals(false, c.value())
}
// applyBasalConstraints tests
@ -354,9 +353,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
// Apply all limits
val d = constraintChecker.getMaxBasalAllowed(validProfile)
Assert.assertEquals(0.8, d.value(), 0.01)
Assert.assertEquals(3, d.reasonList.size)
Assert.assertEquals("DanaR: Limiting max basal rate to 0.80 U/h because of pump limit", d.getMostLimitedReasons(aapsLogger))
Assertions.assertEquals(0.8, d.value(), 0.01)
Assertions.assertEquals(3, d.reasonList.size)
Assertions.assertEquals("DanaR: Limiting max basal rate to 0.80 U/h because of pump limit", d.getMostLimitedReasons(aapsLogger))
}
@Test
@ -381,9 +380,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
// Apply all limits
val i = constraintChecker.getMaxBasalPercentAllowed(validProfile)
Assert.assertEquals(200, i.value())
Assert.assertEquals(6, i.reasonList.size)
Assert.assertEquals("Safety: Limiting max percent rate to 200% because of pump limit", i.getMostLimitedReasons(aapsLogger))
Assertions.assertEquals(200, i.value())
Assertions.assertEquals(6, i.reasonList.size)
Assertions.assertEquals("Safety: Limiting max percent rate to 200% because of pump limit", i.getMostLimitedReasons(aapsLogger))
}
// applyBolusConstraints tests
@ -408,9 +407,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
// Apply all limits
val d = constraintChecker.getMaxBolusAllowed()
Assert.assertEquals(3.0, d.value(), 0.01)
Assert.assertEquals(4, d.reasonList.size) // 2x Safety & RS & R
Assert.assertEquals("Safety: Limiting bolus to 3.0 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
Assertions.assertEquals(3.0, d.value(), 0.01)
Assertions.assertEquals(4, d.reasonList.size) // 2x Safety & RS & R
Assertions.assertEquals("Safety: Limiting bolus to 3.0 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
}
// applyCarbsConstraints tests
@ -421,9 +420,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
// Apply all limits
val i = constraintChecker.getMaxCarbsAllowed()
Assert.assertEquals(48, i.value())
Assert.assertEquals(true, i.reasonList.size == 1)
Assert.assertEquals("Safety: Limiting carbs to 48 g because of max value in preferences", i.getMostLimitedReasons(aapsLogger))
Assertions.assertEquals(48, i.value())
Assertions.assertEquals(true, i.reasonList.size == 1)
Assertions.assertEquals("Safety: Limiting carbs to 48 g because of max value in preferences", i.getMostLimitedReasons(aapsLogger))
}
// applyMaxIOBConstraints tests
@ -438,9 +437,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
// Apply all limits
val d = constraintChecker.getMaxIOBAllowed()
Assert.assertEquals(1.5, d.value(), 0.01)
Assert.assertEquals(d.reasonList.toString(), 2, d.reasonList.size)
Assert.assertEquals("OpenAPSAMA: Limiting IOB to 1.5 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
Assertions.assertEquals(1.5, d.value(), 0.01)
Assertions.assertEquals(2, d.reasonList.size)
Assertions.assertEquals("OpenAPSAMA: Limiting IOB to 1.5 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
}
@Test
@ -454,8 +453,8 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
// Apply all limits
val d = constraintChecker.getMaxIOBAllowed()
Assert.assertEquals(3.0, d.value(), 0.01)
Assert.assertEquals(d.reasonList.toString(), 2, d.reasonList.size)
Assert.assertEquals("OpenAPSSMB: Limiting IOB to 3.0 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
Assertions.assertEquals(3.0, d.value(), 0.01)
Assertions.assertEquals(2, d.reasonList.size)
Assertions.assertEquals("OpenAPSSMB: Limiting IOB to 3.0 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
}
}

View file

@ -4,12 +4,12 @@ import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.HardLimitsMock
import info.nightscout.androidaps.TestBaseWithProfile
import info.nightscout.core.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.database.impl.AppRepository
import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
import info.nightscout.interfaces.constraints.Constraint
import info.nightscout.interfaces.constraints.Constraints
import info.nightscout.interfaces.iob.GlucoseStatusProvider
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.plugin.PluginType
import info.nightscout.interfaces.profiling.Profiler
@ -22,7 +22,7 @@ import info.nightscout.plugins.constraints.safety.SafetyPlugin
import info.nightscout.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.plugins.source.GlimpPlugin
import info.nightscout.shared.sharedPreferences.SP
import org.junit.Assert
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.Mock
@ -91,8 +91,8 @@ class SafetyPluginTest : TestBaseWithProfile() {
pumpDescription.isTempBasalCapable = false
var c = Constraint(true)
c = safetyPlugin.isLoopInvocationAllowed(c)
Assert.assertEquals("Safety: Pump is not temp basal capable", c.getReasons(aapsLogger))
Assert.assertEquals(false, c.value())
Assertions.assertEquals("Safety: Pump is not temp basal capable", c.getReasons(aapsLogger))
Assertions.assertEquals(false, c.value())
}
@Test
@ -101,8 +101,8 @@ class SafetyPluginTest : TestBaseWithProfile() {
`when`(config.isEngineeringModeOrRelease()).thenReturn(false)
var c = Constraint(true)
c = safetyPlugin.isClosedLoopAllowed(c)
Assert.assertTrue(c.getReasons(aapsLogger).contains("Running dev version. Closed loop is disabled."))
Assert.assertEquals(false, c.value())
Assertions.assertTrue(c.getReasons(aapsLogger).contains("Running dev version. Closed loop is disabled."))
Assertions.assertEquals(false, c.value())
}
@Test
@ -110,8 +110,8 @@ class SafetyPluginTest : TestBaseWithProfile() {
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, "open")).thenReturn("open")
var c = Constraint(true)
c = safetyPlugin.isClosedLoopAllowed(c)
Assert.assertTrue(c.getReasons(aapsLogger).contains("Closed loop mode disabled in preferences"))
Assert.assertEquals(false, c.value())
Assertions.assertTrue(c.getReasons(aapsLogger).contains("Closed loop mode disabled in preferences"))
Assertions.assertEquals(false, c.value())
}
@Test
@ -120,8 +120,8 @@ class SafetyPluginTest : TestBaseWithProfile() {
`when`(constraintChecker.isClosedLoopAllowed(anyObject())).thenReturn(Constraint(true))
var c = Constraint(true)
c = openAPSSMBPlugin.isSMBModeEnabled(c)
Assert.assertTrue(c.getReasons(aapsLogger).contains("SMB disabled in preferences"))
Assert.assertEquals(false, c.value())
Assertions.assertTrue(c.getReasons(aapsLogger).contains("SMB disabled in preferences"))
Assertions.assertEquals(false, c.value())
}
@Test
@ -130,8 +130,8 @@ class SafetyPluginTest : TestBaseWithProfile() {
`when`(constraintChecker.isClosedLoopAllowed(anyObject())).thenReturn(Constraint(false))
var c = Constraint(true)
c = safetyPlugin.isSMBModeEnabled(c)
Assert.assertTrue(c.getReasons(aapsLogger).contains("SMB not allowed in open loop mode"))
Assert.assertEquals(false, c.value())
Assertions.assertTrue(c.getReasons(aapsLogger).contains("SMB not allowed in open loop mode"))
Assertions.assertEquals(false, c.value())
}
@Test
@ -139,8 +139,8 @@ class SafetyPluginTest : TestBaseWithProfile() {
`when`(activePlugin.activeBgSource).thenReturn(glimpPlugin)
var c = Constraint(true)
c = safetyPlugin.isAdvancedFilteringEnabled(c)
Assert.assertEquals("Safety: SMB always and after carbs disabled because active BG source doesn\\'t support advanced filtering", c.getReasons(aapsLogger))
Assert.assertEquals(false, c.value())
Assertions.assertEquals("Safety: SMB always and after carbs disabled because active BG source doesn\\'t support advanced filtering", c.getReasons(aapsLogger))
Assertions.assertEquals(false, c.value())
}
@Test
@ -151,13 +151,13 @@ class SafetyPluginTest : TestBaseWithProfile() {
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
val c = Constraint(Constants.REALLYHIGHBASALRATE)
safetyPlugin.applyBasalConstraints(c, validProfile)
Assert.assertEquals(2.0, c.value(), 0.01)
Assert.assertEquals(
Assertions.assertEquals(2.0, c.value(), 0.01)
Assertions.assertEquals(
"""
Safety: Limiting max basal rate to 2.00 U/h because of hard limit
""".trimIndent(), c.getReasons(aapsLogger)
)
Assert.assertEquals("Safety: Limiting max basal rate to 2.00 U/h because of hard limit", c.getMostLimitedReasons(aapsLogger))
Assertions.assertEquals("Safety: Limiting max basal rate to 2.00 U/h because of hard limit", c.getMostLimitedReasons(aapsLogger))
}
@Test
@ -165,8 +165,8 @@ class SafetyPluginTest : TestBaseWithProfile() {
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
val d = Constraint(-0.5)
safetyPlugin.applyBasalConstraints(d, validProfile)
Assert.assertEquals(0.0, d.value(), 0.01)
Assert.assertEquals("Safety: Limiting max basal rate to 0.00 U/h because of it must be positive value", d.getReasons(aapsLogger))
Assertions.assertEquals(0.0, d.value(), 0.01)
Assertions.assertEquals("Safety: Limiting max basal rate to 0.00 U/h because of it must be positive value", d.getReasons(aapsLogger))
}
@Test
@ -178,8 +178,8 @@ class SafetyPluginTest : TestBaseWithProfile() {
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
val i = Constraint(Constants.REALLYHIGHPERCENTBASALRATE)
safetyPlugin.applyBasalPercentConstraints(i, validProfile)
Assert.assertEquals(200, i.value())
Assert.assertEquals(
Assertions.assertEquals(200, i.value())
Assertions.assertEquals(
"""
Safety: Percent rate 1111111% recalculated to 11111.11 U/h with current basal 1.00 U/h
Safety: Limiting max basal rate to 2.00 U/h because of hard limit
@ -187,7 +187,7 @@ Safety: Limiting max percent rate to 200% because of pump limit
Safety: Limiting max basal rate to 500.00 U/h because of pump limit
""".trimIndent(), i.getReasons(aapsLogger)
)
Assert.assertEquals("Safety: Limiting max percent rate to 200% because of pump limit", i.getMostLimitedReasons(aapsLogger))
Assertions.assertEquals("Safety: Limiting max percent rate to 200% because of pump limit", i.getMostLimitedReasons(aapsLogger))
}
@Test
@ -200,15 +200,15 @@ Safety: Limiting max basal rate to 500.00 U/h because of pump limit
openAPSSMBPlugin.setPluginEnabled(PluginType.APS, true)
val i = Constraint(Constants.REALLYHIGHBASALRATE)
openAPSSMBPlugin.applyBasalConstraints(i, validProfile)
Assert.assertEquals(1.0, i.value(), 0.01)
Assert.assertEquals(
Assertions.assertEquals(1.0, i.value(), 0.01)
Assertions.assertEquals(
"""
OpenAPSSMB: Limiting max basal rate to 1.00 U/h because of max value in preferences
OpenAPSSMB: Limiting max basal rate to 4.00 U/h because of max basal multiplier
OpenAPSSMB: Limiting max basal rate to 3.00 U/h because of max daily basal multiplier
""".trimIndent(), i.getReasons(aapsLogger)
)
Assert.assertEquals("OpenAPSSMB: Limiting max basal rate to 1.00 U/h because of max value in preferences", i.getMostLimitedReasons(aapsLogger))
Assertions.assertEquals("OpenAPSSMB: Limiting max basal rate to 1.00 U/h because of max value in preferences", i.getMostLimitedReasons(aapsLogger))
}
@Test
@ -216,15 +216,15 @@ Safety: Limiting max basal rate to 500.00 U/h because of pump limit
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
val i = Constraint(-22)
safetyPlugin.applyBasalPercentConstraints(i, validProfile)
Assert.assertEquals(0, i.value())
Assert.assertEquals(
Assertions.assertEquals(0, i.value())
Assertions.assertEquals(
"""
Safety: Percent rate -22% recalculated to -0.22 U/h with current basal 1.00 U/h
Safety: Limiting max basal rate to 0.00 U/h because of it must be positive value
Safety: Limiting max percent rate to 0% because of pump limit
""".trimIndent(), i.getReasons(aapsLogger)
)
Assert.assertEquals("Safety: Limiting max percent rate to 0% because of pump limit", i.getMostLimitedReasons(aapsLogger))
Assertions.assertEquals("Safety: Limiting max percent rate to 0% because of pump limit", i.getMostLimitedReasons(aapsLogger))
}
@Test
@ -233,14 +233,14 @@ Safety: Limiting max basal rate to 500.00 U/h because of pump limit
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
var d = Constraint(Constants.REALLYHIGHBOLUS)
d = safetyPlugin.applyBolusConstraints(d)
Assert.assertEquals(3.0, d.value(), 0.01)
Assert.assertEquals(
Assertions.assertEquals(3.0, d.value(), 0.01)
Assertions.assertEquals(
"""
Safety: Limiting bolus to 3.0 U because of max value in preferences
Safety: Limiting bolus to 5.0 U because of hard limit
""".trimIndent(), d.getReasons(aapsLogger)
)
Assert.assertEquals("Safety: Limiting bolus to 3.0 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
Assertions.assertEquals("Safety: Limiting bolus to 3.0 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
}
@Test
@ -249,9 +249,9 @@ Safety: Limiting max basal rate to 500.00 U/h because of pump limit
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
var d = Constraint(-22.0)
d = safetyPlugin.applyBolusConstraints(d)
Assert.assertEquals(0.0, d.value(), 0.01)
Assert.assertEquals("Safety: Limiting bolus to 0.0 U because of it must be positive value", d.getReasons(aapsLogger))
Assert.assertEquals("Safety: Limiting bolus to 0.0 U because of it must be positive value", d.getMostLimitedReasons(aapsLogger))
Assertions.assertEquals(0.0, d.value(), 0.01)
Assertions.assertEquals("Safety: Limiting bolus to 0.0 U because of it must be positive value", d.getReasons(aapsLogger))
Assertions.assertEquals("Safety: Limiting bolus to 0.0 U because of it must be positive value", d.getMostLimitedReasons(aapsLogger))
}
@Test
@ -262,13 +262,13 @@ Safety: Limiting max basal rate to 500.00 U/h because of pump limit
// Negative carbs not allowed
var i = Constraint(-22)
safetyPlugin.applyCarbsConstraints(i)
Assert.assertEquals(0, i.value())
Assert.assertEquals("Safety: Limiting carbs to 0 g because of it must be positive value", i.getReasons(aapsLogger))
Assertions.assertEquals(0, i.value())
Assertions.assertEquals("Safety: Limiting carbs to 0 g because of it must be positive value", i.getReasons(aapsLogger))
// Apply all limits
i = safetyPlugin.applyCarbsConstraints(Constraint(Constants.REALLYHIGHCARBS))
Assert.assertEquals(48, i.value())
Assert.assertEquals("Safety: Limiting carbs to 48 g because of max value in preferences", i.getReasons(aapsLogger))
Assertions.assertEquals(48, i.value())
Assertions.assertEquals("Safety: Limiting carbs to 48 g because of max value in preferences", i.getReasons(aapsLogger))
}
@Test
@ -285,22 +285,22 @@ Safety: Limiting max basal rate to 500.00 U/h because of pump limit
// Apply all limits
var d = Constraint(Constants.REALLYHIGHIOB)
d = safetyPlugin.applyMaxIOBConstraints(d)
Assert.assertEquals(HardLimits.MAX_IOB_LGS, d.value(), 0.01)
Assert.assertEquals("Safety: Limiting IOB to 0.0 U because of Low Glucose Suspend", d.getReasons(aapsLogger))
Assert.assertEquals("Safety: Limiting IOB to 0.0 U because of Low Glucose Suspend", d.getMostLimitedReasons(aapsLogger))
Assertions.assertEquals(HardLimits.MAX_IOB_LGS, d.value(), 0.01)
Assertions.assertEquals("Safety: Limiting IOB to 0.0 U because of Low Glucose Suspend", d.getReasons(aapsLogger))
Assertions.assertEquals("Safety: Limiting IOB to 0.0 U because of Low Glucose Suspend", d.getMostLimitedReasons(aapsLogger))
// Apply all limits
d = Constraint(Constants.REALLYHIGHIOB)
val a = openAPSAMAPlugin.applyMaxIOBConstraints(d)
Assert.assertEquals(1.5, a.value(), 0.01)
Assert.assertEquals("OpenAPSAMA: Limiting IOB to 1.5 U because of max value in preferences\nOpenAPSAMA: Limiting IOB to 7.0 U because of hard limit", d.getReasons(aapsLogger))
Assert.assertEquals("OpenAPSAMA: Limiting IOB to 1.5 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
Assertions.assertEquals(1.5, a.value(), 0.01)
Assertions.assertEquals("OpenAPSAMA: Limiting IOB to 1.5 U because of max value in preferences\nOpenAPSAMA: Limiting IOB to 7.0 U because of hard limit", d.getReasons(aapsLogger))
Assertions.assertEquals("OpenAPSAMA: Limiting IOB to 1.5 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
// Apply all limits
d = Constraint(Constants.REALLYHIGHIOB)
val s = openAPSSMBPlugin.applyMaxIOBConstraints(d)
Assert.assertEquals(3.0, s.value(), 0.01)
Assert.assertEquals("OpenAPSSMB: Limiting IOB to 3.0 U because of max value in preferences\nOpenAPSSMB: Limiting IOB to 22.0 U because of hard limit", d.getReasons(aapsLogger))
Assert.assertEquals("OpenAPSSMB: Limiting IOB to 3.0 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
Assertions.assertEquals(3.0, s.value(), 0.01)
Assertions.assertEquals("OpenAPSSMB: Limiting IOB to 3.0 U because of max value in preferences\nOpenAPSSMB: Limiting IOB to 22.0 U because of hard limit", d.getReasons(aapsLogger))
Assertions.assertEquals("OpenAPSSMB: Limiting IOB to 3.0 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
}
}

View file

@ -0,0 +1,6 @@
package info.nightscout.interfaces.iob
interface GlucoseStatusProvider {
val glucoseStatusData: GlucoseStatus?
fun getGlucoseStatusData(allowOldData: Boolean = false): GlucoseStatus?
}

View file

@ -6,7 +6,6 @@ import com.google.common.base.Joiner
import dagger.android.HasAndroidInjector
import info.nightscout.core.extensions.highValueToUnitsToString
import info.nightscout.core.extensions.lowValueToUnitsToString
import info.nightscout.core.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.core.iob.round
import info.nightscout.core.ui.dialogs.OKDialog
import info.nightscout.core.utils.extensions.formatColor
@ -24,6 +23,7 @@ import info.nightscout.interfaces.constraints.Constraint
import info.nightscout.interfaces.constraints.Constraints
import info.nightscout.interfaces.db.PersistenceLayer
import info.nightscout.interfaces.iob.GlucoseStatus
import info.nightscout.interfaces.iob.GlucoseStatusProvider
import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.logging.UserEntryLogger
import info.nightscout.interfaces.plugin.ActivePlugin

View file

@ -3,13 +3,13 @@ package info.nightscout.core.wizard
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.annotations.OpenForTesting
import info.nightscout.core.extensions.valueToUnits
import info.nightscout.core.iob.iobCobCalculator.GlucoseStatusProvider
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.IobCobCalculator
import info.nightscout.interfaces.plugin.PluginBase
import info.nightscout.interfaces.profile.Profile

View file

@ -1,107 +0,0 @@
package info.nightscout.androidaps
import androidx.collection.ArrayMap
import dagger.android.HasAndroidInjector
import info.nightscout.core.extensions.pureProfileFromJson
import info.nightscout.core.profile.ProfileSealed
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.ProfileStore
import info.nightscout.interfaces.profile.PureProfile
import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.utils.DateUtil
import org.json.JSONException
import org.json.JSONObject
import javax.inject.Inject
class ProfileStoreObject(val injector: HasAndroidInjector, override val data: JSONObject, val dateUtil: DateUtil) : ProfileStore {
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var config: Config
@Inject lateinit var rh: ResourceHelper
@Inject lateinit var rxBus: RxBus
@Inject lateinit var hardLimits: HardLimits
init {
injector.androidInjector().inject(this)
}
private val cachedObjects = ArrayMap<String, PureProfile>()
private fun storeUnits(): String? = JsonHelper.safeGetStringAllowNull(data, "units", null)
private fun getStore(): JSONObject? {
try {
if (data.has("store")) return data.getJSONObject("store")
} catch (e: JSONException) {
aapsLogger.error("Unhandled exception", e)
}
return null
}
override fun getStartDate(): Long {
val iso = JsonHelper.safeGetString(data, "startDate") ?: return 0
return try {
dateUtil.fromISODateString(iso)
} catch (e: Exception) {
0
}
}
override fun getDefaultProfile(): PureProfile? = getDefaultProfileName()?.let { getSpecificProfile(it) }
override fun getDefaultProfileJson(): JSONObject? = getDefaultProfileName()?.let { getSpecificProfileJson(it) }
override fun getDefaultProfileName(): String? {
val defaultProfileName = data.optString("defaultProfile")
return if (defaultProfileName.isNotEmpty()) getStore()?.has(defaultProfileName)?.let { defaultProfileName } else null
}
override fun getProfileList(): ArrayList<CharSequence> {
val ret = ArrayList<CharSequence>()
getStore()?.keys()?.let { keys ->
while (keys.hasNext()) {
val profileName = keys.next() as String
ret.add(profileName)
}
}
return ret
}
@Synchronized
override fun getSpecificProfile(profileName: String): PureProfile? {
var profile: PureProfile? = null
val units = JsonHelper.safeGetStringAllowNull(data, "units", storeUnits())
getStore()?.let { store ->
if (store.has(profileName)) {
profile = cachedObjects[profileName]
if (profile == null) {
JsonHelper.safeGetJSONObject(store, profileName, null)?.let { profileObject ->
profile = pureProfileFromJson(profileObject, dateUtil, units)
profile?.let { cachedObjects[profileName] = profile }
}
}
}
}
return profile
}
private fun getSpecificProfileJson(profileName: String): JSONObject? {
getStore()?.let { store ->
if (store.has(profileName))
return JsonHelper.safeGetJSONObject(store, profileName, null)
}
return null
}
override val allProfilesValid: Boolean
get() = getProfileList()
.asSequence()
.map { profileName -> getSpecificProfile(profileName.toString()) }
.map { pureProfile -> pureProfile?.let { ProfileSealed.Pure(pureProfile).isValid("allProfilesValid", activePlugin.activePump, config, rh, rxBus, hardLimits, false) } }
.all { it?.isValid == true }
}

View file

@ -10,7 +10,6 @@ import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.DefaultValueHelper
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.profile.ProfileStore
import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.rx.bus.RxBus
import info.nightscout.shared.interfaces.ResourceHelper
@ -38,18 +37,7 @@ open class TestBaseWithProfile : TestBase() {
val rxBus = RxBus(aapsSchedulers, aapsLogger)
val profileInjector = HasAndroidInjector {
AndroidInjector {
if (it is ProfileStoreObject) {
it.aapsLogger = aapsLogger
it.activePlugin = activePluginProvider
it.config = config
it.rh = rh
it.rxBus = rxBus
it.hardLimits = hardLimits
}
}
}
val profileInjector = HasAndroidInjector { AndroidInjector { } }
private lateinit var invalidProfileJSON: String
private lateinit var validProfileJSON: String
@ -70,32 +58,4 @@ open class TestBaseWithProfile : TestBase() {
`when`(activePluginProvider.activePump).thenReturn(testPumpPlugin)
hardLimits = HardLimitsMock(sp, rh)
}
fun getValidProfileStore(): ProfileStore {
val json = JSONObject()
val store = JSONObject()
store.put(TESTPROFILENAME, JSONObject(validProfileJSON))
json.put("defaultProfile", TESTPROFILENAME)
json.put("store", store)
return ProfileStoreObject(profileInjector, json, dateUtil)
}
fun getInvalidProfileStore1(): ProfileStore {
val json = JSONObject()
val store = JSONObject()
store.put(TESTPROFILENAME, JSONObject(invalidProfileJSON))
json.put("defaultProfile", TESTPROFILENAME)
json.put("store", store)
return ProfileStoreObject(profileInjector, json, dateUtil)
}
fun getInvalidProfileStore2(): ProfileStore {
val json = JSONObject()
val store = JSONObject()
store.put(TESTPROFILENAME, JSONObject(validProfileJSON))
store.put("invalid", JSONObject(invalidProfileJSON))
json.put("defaultProfile", TESTPROFILENAME + "invalid")
json.put("store", store)
return ProfileStoreObject(profileInjector, json, dateUtil)
}
}

View file

@ -1,316 +0,0 @@
package info.nightscout.androidaps.plugins.iob.iobCobCalculator
import android.content.Context
import info.nightscout.androidaps.TestBase
import info.nightscout.core.iob.iobCobCalculator.AutosensDataStoreObject
import info.nightscout.database.entities.GlucoseValue
import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
import org.junit.Assert
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.Mock
class AutosensDataStoreTest : TestBase() {
@Mock lateinit var context: Context
lateinit var dateUtil: DateUtil
private val autosensDataStore = AutosensDataStoreObject()
@BeforeEach
fun mock() {
dateUtil = DateUtil(context)
}
@Test
fun isAbout5minDataTest() {
val bgReadingList: MutableList<GlucoseValue> = ArrayList()
// Super data should not be touched
bgReadingList.clear()
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.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 = bgReadingList
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
// too much shifted data should return false
bgReadingList.clear()
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(9).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.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 = bgReadingList
Assert.assertEquals(false, autosensDataStore.isAbout5minData(aapsLogger))
// too much shifted and missing data should return false
bgReadingList.clear()
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(9).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.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 = bgReadingList
Assert.assertEquals(false, autosensDataStore.isAbout5minData(aapsLogger))
// too much shifted and missing data should return false
bgReadingList.clear()
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(83).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(78).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(73).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(68).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(63).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(58).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(53).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(48).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(43).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(38).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(33).plus(T.secs(1)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(28).plus(T.secs(0)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(23).plus(T.secs(0)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(16).plus(T.secs(36)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
autosensDataStore.bgReadings = bgReadingList
Assert.assertEquals(false, autosensDataStore.isAbout5minData(aapsLogger))
// slightly shifted data should return true
bgReadingList.clear()
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).plus(T.secs(10)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.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 = bgReadingList
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
// slightly shifted and missing data should return true
bgReadingList.clear()
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).plus(T.secs(10)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.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 = bgReadingList
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
}
@Test
fun createBucketedData5minTest1() {
val bgReadingList: MutableList<GlucoseValue> = ArrayList()
// Super data should not be touched
bgReadingList.clear()
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.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 = bgReadingList
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
Assert.assertEquals(bgReadingList[0].timestamp, autosensDataStore.bucketedData!![0].timestamp)
Assert.assertEquals(bgReadingList[3].timestamp, autosensDataStore.bucketedData!![3].timestamp)
Assert.assertEquals(bgReadingList.size.toLong(), autosensDataStore.bucketedData!!.size.toLong())
// Missing value should be replaced
bgReadingList.clear()
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).plus(T.secs(10)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.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 = bgReadingList
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
Assert.assertEquals(bgReadingList[0].timestamp, autosensDataStore.bucketedData!![0].timestamp)
Assert.assertEquals(bgReadingList[2].timestamp, autosensDataStore.bucketedData!![3].timestamp)
Assert.assertEquals(bgReadingList.size + 1.toLong(), autosensDataStore.bucketedData!!.size.toLong())
// drift should be cleared
bgReadingList.clear()
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs() + T.secs(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs() + T.secs(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs() + T.secs(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(0).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
autosensDataStore.bgReadings = bgReadingList
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
Assert.assertEquals(T.mins(20).msecs(), autosensDataStore.bucketedData!![0].timestamp)
Assert.assertEquals(T.mins(15).msecs(), autosensDataStore.bucketedData!![1].timestamp)
Assert.assertEquals(T.mins(10).msecs(), autosensDataStore.bucketedData!![2].timestamp)
Assert.assertEquals(T.mins(5).msecs(), autosensDataStore.bucketedData!![3].timestamp)
Assert.assertEquals(bgReadingList.size.toLong(), autosensDataStore.bucketedData!!.size.toLong())
// bucketed data should return null if not enough bg data
bgReadingList.clear()
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(30).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.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 = bgReadingList
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
Assert.assertEquals(null, autosensDataStore.bucketedData)
// data should be reconstructed
bgReadingList.clear()
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(50).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 90.0, timestamp = T.mins(45).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 40.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
autosensDataStore.bgReadings = bgReadingList
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
Assert.assertEquals(T.mins(50).msecs(), autosensDataStore.bucketedData!![0].timestamp)
Assert.assertEquals(T.mins(20).msecs(), autosensDataStore.bucketedData!![6].timestamp)
Assert.assertEquals(7, autosensDataStore.bucketedData!!.size.toLong())
Assert.assertEquals(100.0, autosensDataStore.bucketedData!![0].value, 1.0)
Assert.assertEquals(90.0, autosensDataStore.bucketedData!![1].value, 1.0)
Assert.assertEquals(50.0, autosensDataStore.bucketedData!![5].value, 1.0)
Assert.assertEquals(40.0, autosensDataStore.bucketedData!![6].value, 1.0)
// non 5min data should be reconstructed
bgReadingList.clear()
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(50).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 96.0, timestamp = T.mins(48).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 40.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
autosensDataStore.bgReadings = bgReadingList
Assert.assertEquals(false, autosensDataStore.isAbout5minData(aapsLogger))
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
Assert.assertEquals(T.mins(50).msecs(), autosensDataStore.bucketedData!![0].timestamp)
Assert.assertEquals(T.mins(20).msecs(), autosensDataStore.bucketedData!![6].timestamp)
Assert.assertEquals(7, autosensDataStore.bucketedData!!.size.toLong())
Assert.assertEquals(100.0, autosensDataStore.bucketedData!![0].value, 1.0)
Assert.assertEquals(90.0, autosensDataStore.bucketedData!![1].value, 1.0)
Assert.assertEquals(50.0, autosensDataStore.bucketedData!![5].value, 1.0)
Assert.assertEquals(40.0, autosensDataStore.bucketedData!![6].value, 1.0)
}
@Test
fun createBucketedData5minTest2() {
val bgReadingList: MutableList<GlucoseValue> = ArrayList()
//bucketed data should be null if no bg data available
autosensDataStore.bgReadings = ArrayList()
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
Assert.assertEquals(null, autosensDataStore.bucketedData)
// real data gap test
bgReadingList.clear()
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T13:34:55Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T13:14:55Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T13:09:55Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T13:04:55Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T12:59:55Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T12:54:55Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T12:49:55Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T12:44:55Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T12:39:55Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T12:34:55Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T12:29:56Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T12:24:55Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T12:19:56Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T12:14:56Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T12:09:56Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T12:04:56Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T11:59:55Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T04:29:57Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T04:24:56Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T04:19:57Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T04:14:57Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T04:10:03Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T04:04:56Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T03:59:56Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T03:54:56Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T03:50:03Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-09-05T03:44:57Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
autosensDataStore.bgReadings = bgReadingList
autosensDataStore.referenceTime = -1
Assert.assertEquals(true, autosensDataStore.isAbout5minData(aapsLogger))
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
Assert.assertEquals(dateUtil.fromISODateString("2018-09-05T13:34:57Z"), autosensDataStore.bucketedData!![0].timestamp)
Assert.assertEquals(dateUtil.fromISODateString("2018-09-05T03:44:57Z"), autosensDataStore.bucketedData!![autosensDataStore.bucketedData!!.size - 1].timestamp)
// 5min 4sec data
bgReadingList.clear()
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T06:33:40Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T06:28:36Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T06:23:32Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T06:18:28Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T06:13:24Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T06:08:19Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T06:03:16Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T05:58:11Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T05:53:07Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T05:48:03Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T05:42:58Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T05:37:54Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T05:32:51Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T05:27:46Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T05:22:42Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T05:17:38Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T05:12:33Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T05:07:29Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T05:02:26Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T04:57:21Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = dateUtil.fromISODateString("2018-10-05T04:52:17Z"), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
autosensDataStore.bgReadings = bgReadingList
Assert.assertEquals(false, autosensDataStore.isAbout5minData(aapsLogger))
}
@Test
fun bgReadingsTest() {
val bgReadingList: List<GlucoseValue> = ArrayList()
autosensDataStore.bgReadings = bgReadingList
Assert.assertEquals(bgReadingList, autosensDataStore.bgReadings)
}
@Test
fun roundUpTimeTest() {
Assert.assertEquals(T.mins(3).msecs(), autosensDataStore.roundUpTime(T.secs(155).msecs()))
}
@Test
fun findNewerTest() {
val bgReadingList: MutableList<GlucoseValue> = ArrayList()
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.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 = bgReadingList
Assert.assertEquals(T.mins(10).msecs(), autosensDataStore.findNewer(T.mins(8).msecs())!!.timestamp)
Assert.assertEquals(T.mins(5).msecs(), autosensDataStore.findNewer(T.mins(5).msecs())!!.timestamp)
Assert.assertEquals(T.mins(10).msecs(), autosensDataStore.findNewer(T.mins(10).msecs())!!.timestamp)
Assert.assertEquals(T.mins(20).msecs(), autosensDataStore.findNewer(T.mins(20).msecs())!!.timestamp)
Assert.assertEquals(null, autosensDataStore.findNewer(T.mins(22).msecs()))
}
@Test
fun findOlderTest() {
val bgReadingList: MutableList<GlucoseValue> = ArrayList()
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.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 = bgReadingList
Assert.assertEquals(T.mins(5).msecs(), autosensDataStore.findOlder(T.mins(8).msecs())!!.timestamp)
Assert.assertEquals(T.mins(5).msecs(), autosensDataStore.findOlder(T.mins(5).msecs())!!.timestamp)
Assert.assertEquals(T.mins(10).msecs(), autosensDataStore.findOlder(T.mins(10).msecs())!!.timestamp)
Assert.assertEquals(T.mins(20).msecs(), autosensDataStore.findOlder(T.mins(20).msecs())!!.timestamp)
Assert.assertEquals(null, autosensDataStore.findOlder(T.mins(4).msecs()))
}
@Test
fun findPreviousTimeFromBucketedDataTest() {
val bgReadingList: MutableList<GlucoseValue> = ArrayList()
autosensDataStore.bgReadings = bgReadingList
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
Assert.assertEquals(null, autosensDataStore.findPreviousTimeFromBucketedData(1000))
// Super data should not be touched
bgReadingList.clear()
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
bgReadingList.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 = bgReadingList
autosensDataStore.createBucketedData(aapsLogger, dateUtil)
Assert.assertEquals(null, autosensDataStore.findPreviousTimeFromBucketedData(T.mins(4).msecs()))
Assert.assertEquals(T.mins(5).msecs(), autosensDataStore.findPreviousTimeFromBucketedData(T.mins(6).msecs()))
Assert.assertEquals(T.mins(20).msecs(), autosensDataStore.findPreviousTimeFromBucketedData(T.mins(20).msecs()))
Assert.assertEquals(T.mins(20).msecs(), autosensDataStore.findPreviousTimeFromBucketedData(T.mins(25).msecs()))
}
}

View file

@ -16,6 +16,7 @@ import info.nightscout.implementation.XDripBroadcastImpl
import info.nightscout.implementation.androidNotification.NotificationHolderImpl
import info.nightscout.implementation.constraints.ConstraintsImpl
import info.nightscout.implementation.db.PersistenceLayerImpl
import info.nightscout.implementation.iob.GlucoseStatusProviderImpl
import info.nightscout.implementation.logging.LoggerUtilsImpl
import info.nightscout.implementation.overview.OverviewDataImpl
import info.nightscout.implementation.plugin.PluginStore
@ -48,6 +49,7 @@ import info.nightscout.interfaces.Translator
import info.nightscout.interfaces.XDripBroadcast
import info.nightscout.interfaces.constraints.Constraints
import info.nightscout.interfaces.db.PersistenceLayer
import info.nightscout.interfaces.iob.GlucoseStatusProvider
import info.nightscout.interfaces.logging.LoggerUtils
import info.nightscout.interfaces.logging.UserEntryLogger
import info.nightscout.interfaces.plugin.ActivePlugin
@ -124,5 +126,6 @@ abstract class ImplementationModule {
@Binds fun bindsStorage(fileStorage: FileStorage): Storage
@Binds fun bindsReceiverStatusStore(receiverStatusStoreImpl: ReceiverStatusStoreImpl): ReceiverStatusStore
@Binds fun bindsUserEntryPresentationHelper(userEntryPresentationHelperImpl: UserEntryPresentationHelperImpl): UserEntryPresentationHelper
@Binds fun bindsGlucoseStatusProvider(glucoseStatusProviderImpl: GlucoseStatusProviderImpl): GlucoseStatusProvider
}
}

View file

@ -1,10 +1,11 @@
package info.nightscout.core.iob.iobCobCalculator
package info.nightscout.implementation.iob
import dagger.Reusable
import info.nightscout.androidaps.annotations.OpenForTesting
import info.nightscout.core.iob.asRounded
import info.nightscout.core.iob.log
import info.nightscout.interfaces.iob.GlucoseStatus
import info.nightscout.interfaces.iob.GlucoseStatusProvider
import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
@ -14,16 +15,16 @@ import kotlin.math.roundToLong
@Reusable
@OpenForTesting
class GlucoseStatusProvider @Inject constructor(
class GlucoseStatusProviderImpl @Inject constructor(
private val aapsLogger: AAPSLogger,
private val iobCobCalculator: IobCobCalculator,
private val dateUtil: DateUtil
) {
) : GlucoseStatusProvider {
val glucoseStatusData: GlucoseStatus?
override val glucoseStatusData: GlucoseStatus?
get() = getGlucoseStatusData()
fun getGlucoseStatusData(allowOldData: Boolean = false): GlucoseStatus? {
override fun getGlucoseStatusData(allowOldData: Boolean): GlucoseStatus? {
val data = iobCobCalculator.ads.getBgReadingsDataTableCopy()
val sizeRecords = data.size
if (sizeRecords == 0) {

View file

@ -54,7 +54,8 @@ class ProfileStoreObject(val injector: HasAndroidInjector, override val data: JS
}
override fun getDefaultProfile(): PureProfile? = getDefaultProfileName()?.let { getSpecificProfile(it) }
override fun getDefaultProfileJson(): JSONObject? = getDefaultProfileName()?.let { getSpecificProfileJson(it) }
override fun getDefaultProfileJson(): JSONObject? =
getDefaultProfileName()?.let { getSpecificProfileJson(it) }
override fun getDefaultProfileName(): String? {
val defaultProfileName = data.optString("defaultProfile")

View file

@ -0,0 +1,83 @@
package info.nightscout.androidaps
import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import javax.inject.Inject
import kotlin.math.max
import kotlin.math.min
class HardLimitsMock @Inject constructor(
private val sp: SP,
private val rh: ResourceHelper
) : HardLimits {
companion object {
private const val CHILD = 0
private const val TEENAGE = 1
private const val ADULT = 2
private const val RESISTANT_ADULT = 3
private const val PREGNANT = 4
private val MAX_BOLUS = doubleArrayOf(5.0, 10.0, 17.0, 25.0, 60.0)
// Very Hard Limits Ranges
// First value is the Lowest and second value is the Highest a Limit can define
val VERY_HARD_LIMIT_MIN_BG = doubleArrayOf(80.0, 180.0)
val VERY_HARD_LIMIT_MAX_BG = doubleArrayOf(90.0, 200.0)
val VERY_HARD_LIMIT_TARGET_BG = doubleArrayOf(80.0, 200.0)
// Very Hard Limits Ranges for Temp Targets
val VERY_HARD_LIMIT_TEMP_MIN_BG = intArrayOf(72, 180)
val VERY_HARD_LIMIT_TEMP_MAX_BG = intArrayOf(72, 270)
val VERY_HARD_LIMIT_TEMP_TARGET_BG = intArrayOf(72, 200)
val MIN_DIA = doubleArrayOf(5.0, 5.0, 5.0, 5.0, 5.0)
val MAX_DIA = doubleArrayOf(9.0, 9.0, 9.0, 9.0, 10.0)
val MIN_IC = doubleArrayOf(2.0, 2.0, 2.0, 2.0, 0.3)
val MAX_IC = doubleArrayOf(100.0, 100.0, 100.0, 100.0, 100.0)
const val MIN_ISF = 2.0 // mgdl
const val MAX_ISF = 1000.0 // mgdl
val MAX_IOB_AMA = doubleArrayOf(3.0, 5.0, 7.0, 12.0, 25.0)
val MAX_IOB_SMB = doubleArrayOf(7.0, 13.0, 22.0, 30.0, 70.0)
val MAX_BASAL = doubleArrayOf(2.0, 5.0, 10.0, 12.0, 25.0)
//LGS Hard limits
//No IOB at all
const val MAX_IOB_LGS = 0.0
}
private fun loadAge(): Int = when (sp.getString(info.nightscout.core.utils.R.string.key_age, "")) {
rh.gs(info.nightscout.core.utils.R.string.key_child) -> CHILD
rh.gs(info.nightscout.core.utils.R.string.key_teenage) -> TEENAGE
rh.gs(info.nightscout.core.utils.R.string.key_adult) -> ADULT
rh.gs(info.nightscout.core.utils.R.string.key_resistantadult) -> RESISTANT_ADULT
rh.gs(info.nightscout.core.utils.R.string.key_pregnant) -> PREGNANT
else -> ADULT
}
override fun maxBolus(): Double = MAX_BOLUS[loadAge()]
override fun maxIobAMA(): Double = MAX_IOB_AMA[loadAge()]
override fun maxIobSMB(): Double = MAX_IOB_SMB[loadAge()]
override fun maxBasal(): Double = MAX_BASAL[loadAge()]
override fun minDia(): Double = MIN_DIA[loadAge()]
override fun maxDia(): Double = MAX_DIA[loadAge()]
override fun minIC(): Double = MIN_IC[loadAge()]
override fun maxIC(): Double = MAX_IC[loadAge()]
// safety checks
override fun checkHardLimits(value: Double, valueName: Int, lowLimit: Double, highLimit: Double): Boolean =
value == verifyHardLimits(value, valueName, lowLimit, highLimit)
override fun isInRange(value: Double, lowLimit: Double, highLimit: Double): Boolean =
value in lowLimit..highLimit
override fun verifyHardLimits(value: Double, valueName: Int, lowLimit: Double, highLimit: Double): Double {
var newValue = value
if (newValue < lowLimit || newValue > highLimit) {
newValue = max(newValue, lowLimit)
newValue = min(newValue, highLimit)
}
return newValue
}
}

View file

@ -14,8 +14,10 @@ import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.profile.ProfileStore
import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.rx.bus.RxBus
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import org.json.JSONObject
import org.junit.jupiter.api.BeforeEach
@ -37,25 +39,46 @@ open class TestBaseWithProfile : TestBase() {
@Mock lateinit var profileFunction: ProfileFunction
@Mock lateinit var config: Config
@Mock lateinit var context: Context
@Mock lateinit var sp: SP
private lateinit var hardLimits: HardLimits
lateinit var dateUtil: DateUtil
val rxBus = RxBus(aapsSchedulers, aapsLogger)
val profileInjector = HasAndroidInjector { AndroidInjector { } }
val profileInjector = HasAndroidInjector {
AndroidInjector {
if (it is ProfileStoreObject) {
it.aapsLogger = aapsLogger
it.activePlugin = activePluginProvider
it.config = config
it.rh = rh
it.rxBus = rxBus
it.hardLimits = hardLimits
}
}
}
private lateinit var validProfileJSON: String
private lateinit var invalidProfileJSON: String
lateinit var validProfile: ProfileSealed.Pure
lateinit var effectiveProfileSwitch: EffectiveProfileSwitch
lateinit var testPumpPlugin: TestPumpPlugin
@Suppress("PropertyName") val TESTPROFILENAME = "someProfile"
@BeforeEach
fun prepareMock() {
invalidProfileJSON = "{\"dia\":\"1\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"3\"}," +
"{\"time\":\"2:00\",\"value\":\"3.4\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4.5\"}]," +
"\"target_high\":[{\"time\":\"00:00\",\"value\":\"7\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}"
validProfileJSON = "{\"dia\":\"5\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"3\"}," +
"{\"time\":\"2:00\",\"value\":\"3.4\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4.5\"}]," +
"\"target_high\":[{\"time\":\"00:00\",\"value\":\"7\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}"
testPumpPlugin = TestPumpPlugin(profileInjector)
`when`(activePluginProvider.activePump).thenReturn(testPumpPlugin)
dateUtil = Mockito.spy(DateUtil(context))
`when`(dateUtil.now()).thenReturn(1656358822000)
hardLimits = HardLimitsMock(sp, rh)
validProfile = ProfileSealed.Pure(pureProfileFromJson(JSONObject(validProfileJSON), dateUtil)!!)
effectiveProfileSwitch = EffectiveProfileSwitch(
timestamp = dateUtil.now(),
@ -175,4 +198,23 @@ open class TestBaseWithProfile : TestBase() {
json.put("store", store)
return ProfileStoreObject(profileInjector, json, dateUtil)
}
fun getInvalidProfileStore1(): ProfileStore {
val json = JSONObject()
val store = JSONObject()
store.put(TESTPROFILENAME, JSONObject(invalidProfileJSON))
json.put("defaultProfile", TESTPROFILENAME)
json.put("store", store)
return ProfileStoreObject(profileInjector, json, dateUtil)
}
fun getInvalidProfileStore2(): ProfileStore {
val json = JSONObject()
val store = JSONObject()
store.put(TESTPROFILENAME, JSONObject(validProfileJSON))
store.put("invalid", JSONObject(invalidProfileJSON))
json.put("defaultProfile", TESTPROFILENAME + "invalid")
json.put("store", store)
return ProfileStoreObject(profileInjector, json, dateUtil)
}
}

View file

@ -26,7 +26,7 @@ class TestPumpPlugin(val injector: HasAndroidInjector) : Pump {
val lastData = 0L
val baseBasal = 0.0
override val pumpDescription = PumpDescription()
override var pumpDescription = PumpDescription()
override fun isInitialized(): Boolean = true
override fun isSuspended(): Boolean = false

View file

@ -1,8 +1,7 @@
package info.nightscout.androidaps.plugins.iob.iobCalculator
package info.nightscout.implementation.iob
import info.nightscout.androidaps.TestBase
import info.nightscout.core.iob.asRounded
import info.nightscout.core.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.core.iob.log
import info.nightscout.database.entities.GlucoseValue
import info.nightscout.interfaces.aps.AutosensDataStore
@ -10,16 +9,15 @@ import info.nightscout.interfaces.iob.GlucoseStatus
import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
import org.junit.Assert
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.Mockito
/**
* Created by mike on 26.03.2018.
*/
@Suppress("SpellCheckingInspection")
class GlucoseStatusTest : TestBase() {
@Mock lateinit var dateUtil: DateUtil
@ -28,85 +26,85 @@ class GlucoseStatusTest : TestBase() {
@BeforeEach
fun prepare() {
`when`(iobCobCalculatorPlugin.ads).thenReturn(autosensDataStore)
Mockito.`when`(iobCobCalculatorPlugin.ads).thenReturn(autosensDataStore)
}
@Test fun toStringShouldBeOverloaded() {
val glucoseStatus = GlucoseStatus(glucose = 0.0, noise = 0.0, delta = 0.0, shortAvgDelta = 0.0, longAvgDelta = 0.0, date = 0)
Assert.assertEquals(true, glucoseStatus.log().contains("Delta"))
Assertions.assertEquals(true, glucoseStatus.log().contains("Delta"))
}
@Test fun roundTest() {
val glucoseStatus = GlucoseStatus(glucose = 100.11111, noise = 0.0, delta = 0.0, shortAvgDelta = 0.0, longAvgDelta = 0.0, date = 0)
Assert.assertEquals(100.1, glucoseStatus.asRounded().glucose, 0.0001)
Assertions.assertEquals(100.1, glucoseStatus.asRounded().glucose, 0.0001)
}
@Test fun calculateValidGlucoseStatus() {
`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(generateValidBgData())
val glucoseStatus = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData!!
Assert.assertEquals(214.0, glucoseStatus.glucose, 0.001)
Assert.assertEquals(-2.0, glucoseStatus.delta, 0.001)
Assert.assertEquals(-2.5, glucoseStatus.shortAvgDelta, 0.001) // -2 -2.5 -3 deltas are relative to current value
Assert.assertEquals(-2.0, glucoseStatus.longAvgDelta, 0.001) // -2 -2 -2 -2
Assert.assertEquals(1514766900000L, glucoseStatus.date) // latest date
Mockito.`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(generateValidBgData())
val glucoseStatus = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData!!
Assertions.assertEquals(214.0, glucoseStatus.glucose, 0.001)
Assertions.assertEquals(-2.0, glucoseStatus.delta, 0.001)
Assertions.assertEquals(-2.5, glucoseStatus.shortAvgDelta, 0.001) // -2 -2.5 -3 deltas are relative to current value
Assertions.assertEquals(-2.0, glucoseStatus.longAvgDelta, 0.001) // -2 -2 -2 -2
Assertions.assertEquals(1514766900000L, glucoseStatus.date) // latest date
}
@Test fun calculateMostRecentGlucoseStatus() {
`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(generateMostRecentBgData())
val glucoseStatus: GlucoseStatus = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData!!
Assert.assertEquals(215.0, glucoseStatus.glucose, 0.001) // (214+216) / 2
Assert.assertEquals(-1.0, glucoseStatus.delta, 0.001)
Assert.assertEquals(-1.0, glucoseStatus.shortAvgDelta, 0.001)
Assert.assertEquals(0.0, glucoseStatus.longAvgDelta, 0.001)
Assert.assertEquals(1514766900000L, glucoseStatus.date) // latest date, even when averaging
Mockito.`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(generateMostRecentBgData())
val glucoseStatus: GlucoseStatus = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData!!
Assertions.assertEquals(215.0, glucoseStatus.glucose, 0.001) // (214+216) / 2
Assertions.assertEquals(-1.0, glucoseStatus.delta, 0.001)
Assertions.assertEquals(-1.0, glucoseStatus.shortAvgDelta, 0.001)
Assertions.assertEquals(0.0, glucoseStatus.longAvgDelta, 0.001)
Assertions.assertEquals(1514766900000L, glucoseStatus.date) // latest date, even when averaging
}
@Test fun oneRecordShouldProduceZeroDeltas() {
`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(generateOneCurrentRecordBgData())
val glucoseStatus: GlucoseStatus = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData!!
Assert.assertEquals(214.0, glucoseStatus.glucose, 0.001)
Assert.assertEquals(0.0, glucoseStatus.delta, 0.001)
Assert.assertEquals(0.0, glucoseStatus.shortAvgDelta, 0.001) // -2 -2.5 -3 deltas are relative to current value
Assert.assertEquals(0.0, glucoseStatus.longAvgDelta, 0.001) // -2 -2 -2 -2
Assert.assertEquals(1514766900000L, glucoseStatus.date) // latest date
Mockito.`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(generateOneCurrentRecordBgData())
val glucoseStatus: GlucoseStatus = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData!!
Assertions.assertEquals(214.0, glucoseStatus.glucose, 0.001)
Assertions.assertEquals(0.0, glucoseStatus.delta, 0.001)
Assertions.assertEquals(0.0, glucoseStatus.shortAvgDelta, 0.001) // -2 -2.5 -3 deltas are relative to current value
Assertions.assertEquals(0.0, glucoseStatus.longAvgDelta, 0.001) // -2 -2 -2 -2
Assertions.assertEquals(1514766900000L, glucoseStatus.date) // latest date
}
@Test fun insufficientDataShouldReturnNull() {
`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(generateInsufficientBgData())
val glucoseStatus: GlucoseStatus? = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData
Assert.assertEquals(null, glucoseStatus)
Mockito.`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(generateInsufficientBgData())
val glucoseStatus: GlucoseStatus? = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData
Assertions.assertEquals(null, glucoseStatus)
}
@Test fun oldDataShouldReturnNull() {
`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(generateOldBgData())
val glucoseStatus: GlucoseStatus? = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData
Assert.assertEquals(null, glucoseStatus)
Mockito.`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(generateOldBgData())
val glucoseStatus: GlucoseStatus? = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData
Assertions.assertEquals(null, glucoseStatus)
}
@Test fun returnOldDataIfAllowed() {
`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(generateOldBgData())
val glucoseStatus: GlucoseStatus? = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).getGlucoseStatusData(true)
Assert.assertNotEquals(null, glucoseStatus)
Mockito.`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(generateOldBgData())
val glucoseStatus: GlucoseStatus? = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil).getGlucoseStatusData(true)
Assertions.assertNotEquals(null, glucoseStatus)
}
@Test fun averageShouldNotFailOnEmptyArray() {
Assert.assertEquals(0.0, GlucoseStatusProvider.average(ArrayList()), 0.001)
Assertions.assertEquals(0.0, GlucoseStatusProviderImpl.average(ArrayList()), 0.001)
}
@Test fun calculateGlucoseStatusForLibreTestBgData() {
`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(generateLibreTestData())
val glucoseStatus: GlucoseStatus = GlucoseStatusProvider(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData!!
Assert.assertEquals(100.0, glucoseStatus.glucose, 0.001) //
Assert.assertEquals(-10.0, glucoseStatus.delta, 0.001)
Assert.assertEquals(-10.0, glucoseStatus.shortAvgDelta, 0.001)
Assert.assertEquals(-10.0, glucoseStatus.longAvgDelta, 0.001)
Assert.assertEquals(1514766900000L, glucoseStatus.date) // latest date
Mockito.`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(generateLibreTestData())
val glucoseStatus: GlucoseStatus = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData!!
Assertions.assertEquals(100.0, glucoseStatus.glucose, 0.001) //
Assertions.assertEquals(-10.0, glucoseStatus.delta, 0.001)
Assertions.assertEquals(-10.0, glucoseStatus.shortAvgDelta, 0.001)
Assertions.assertEquals(-10.0, glucoseStatus.longAvgDelta, 0.001)
Assertions.assertEquals(1514766900000L, glucoseStatus.date) // latest date
}
@BeforeEach
fun initMocking() {
`when`(dateUtil.now()).thenReturn(1514766900000L + T.mins(1).msecs())
`when`(iobCobCalculatorPlugin.ads).thenReturn(autosensDataStore)
Mockito.`when`(dateUtil.now()).thenReturn(1514766900000L + T.mins(1).msecs())
Mockito.`when`(iobCobCalculatorPlugin.ads).thenReturn(autosensDataStore)
}
// [{"mgdl":214,"mills":1521895773113,"device":"xDrip-DexcomG5","direction":"Flat","filtered":191040,"unfiltered":205024,"noise":1,"rssi":100},{"mgdl":219,"mills":1521896073352,"device":"xDrip-DexcomG5","direction":"Flat","filtered":200160,"unfiltered":209760,"noise":1,"rssi":100},{"mgdl":222,"mills":1521896372890,"device":"xDrip-DexcomG5","direction":"Flat","filtered":207360,"unfiltered":212512,"noise":1,"rssi":100},{"mgdl":220,"mills":1521896673062,"device":"xDrip-DexcomG5","direction":"Flat","filtered":211488,"unfiltered":210688,"noise":1,"rssi":100},{"mgdl":193,"mills":1521896972933,"device":"xDrip-DexcomG5","direction":"Flat","filtered":212384,"unfiltered":208960,"noise":1,"rssi":100},{"mgdl":181,"mills":1521897273336,"device":"xDrip-DexcomG5","direction":"SingleDown","filtered":210592,"unfiltered":204320,"noise":1,"rssi":100},{"mgdl":176,"mills":1521897572875,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":206720,"unfiltered":197440,"noise":1,"rssi":100},{"mgdl":168,"mills":1521897872929,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":201024,"unfiltered":187904,"noise":1,"rssi":100},{"mgdl":161,"mills":1521898172814,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":193376,"unfiltered":178144,"noise":1,"rssi":100},{"mgdl":148,"mills":1521898472879,"device":"xDrip-DexcomG5","direction":"SingleDown","filtered":183264,"unfiltered":161216,"noise":1,"rssi":100},{"mgdl":139,"mills":1521898772862,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":170784,"unfiltered":148928,"noise":1,"rssi":100},{"mgdl":132,"mills":1521899072896,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":157248,"unfiltered":139552,"noise":1,"rssi":100},{"mgdl":125,"mills":1521899372834,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":144416,"unfiltered":129616.00000000001,"noise":1,"rssi":100},{"mgdl":128,"mills":1521899973456,"device":"xDrip-DexcomG5","direction":"Flat","filtered":130240.00000000001,"unfiltered":133536,"noise":1,"rssi":100},{"mgdl":132,"mills":1521900573287,"device":"xDrip-DexcomG5","direction":"Flat","filtered":133504,"unfiltered":138720,"noise":1,"rssi":100},{"mgdl":127,"mills":1521900873711,"device":"xDrip-DexcomG5","direction":"Flat","filtered":136480,"unfiltered":132992,"noise":1,"rssi":100},{"mgdl":127,"mills":1521901180151,"device":"xDrip-DexcomG5","direction":"Flat","filtered":136896,"unfiltered":132128,"noise":1,"rssi":100},{"mgdl":125,"mills":1521901473582,"device":"xDrip-DexcomG5","direction":"Flat","filtered":134624,"unfiltered":129696,"noise":1,"rssi":100},{"mgdl":120,"mills":1521901773597,"device":"xDrip-DexcomG5","direction":"Flat","filtered":130704.00000000001,"unfiltered":123376,"noise":1,"rssi":100},{"mgdl":116,"mills":1521902075855,"device":"xDrip-DexcomG5","direction":"Flat","filtered":126272,"unfiltered":118448,"noise":1,"rssi":100}]
@ -154,13 +152,40 @@ class GlucoseStatusTest : TestBase() {
// Now
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = latestReading, timestamp = endTime, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
// One minute ago
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = latestReading, timestamp = endTime - 1000 * 60 * 1, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
list.add(
GlucoseValue(
raw = 0.0,
noise = 0.0,
value = latestReading,
timestamp = endTime - 1000 * 60 * 1,
sourceSensor = GlucoseValue.SourceSensor.UNKNOWN,
trendArrow = GlucoseValue.TrendArrow.FLAT
)
)
// Two minutes ago
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = latestReading, timestamp = endTime - 1000 * 60 * 2, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
list.add(
GlucoseValue(
raw = 0.0,
noise = 0.0,
value = latestReading,
timestamp = endTime - 1000 * 60 * 2,
sourceSensor = GlucoseValue.SourceSensor.UNKNOWN,
trendArrow = GlucoseValue.TrendArrow.FLAT
)
)
// Three minutes and beyond at constant rate
for (i in 3..49)
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = latestReading + i * 2, timestamp = endTime - 1000 * 60 * i, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
list.add(
GlucoseValue(
raw = 0.0,
noise = 0.0,
value = latestReading + i * 2,
timestamp = endTime - 1000 * 60 * i,
sourceSensor = GlucoseValue.SourceSensor.UNKNOWN,
trendArrow = GlucoseValue.TrendArrow.FLAT
)
)
return list
}
}

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.interfaces
package info.nightscout.implementation.profile
import info.nightscout.androidaps.TestBaseWithProfile
import info.nightscout.interfaces.profile.PureProfile

View file

@ -37,7 +37,7 @@ import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import io.reactivex.rxjava3.core.Single
import org.junit.Assert
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.Mock
@ -51,7 +51,6 @@ class CommandQueueImplementationTest : TestBaseWithProfile() {
@Mock lateinit var constraintChecker: Constraints
@Mock lateinit var activePlugin: ActivePlugin
@Mock lateinit var sp: SP
@Mock lateinit var powerManager: PowerManager
@Mock lateinit var repository: AppRepository
@Mock lateinit var uiInteraction: UiInteraction
@ -115,7 +114,6 @@ class CommandQueueImplementationTest : TestBaseWithProfile() {
}
private lateinit var commandQueue: CommandQueueImplementation
private lateinit var testPumpPlugin: TestPumpPlugin
@BeforeEach
fun prepare() {
@ -170,108 +168,108 @@ class CommandQueueImplementationTest : TestBaseWithProfile() {
commandQueue.handler = handler
// start with empty queue
Assert.assertEquals(0, commandQueue.size())
Assertions.assertEquals(0, commandQueue.size())
// add bolus command
commandQueue.bolus(DetailedBolusInfo(), null)
Assert.assertEquals(1, commandQueue.size())
Assertions.assertEquals(1, commandQueue.size())
commandQueue.waitForFinishedThread()
Thread.sleep(1000)
Assert.assertEquals(0, commandQueue.size())
Assertions.assertEquals(0, commandQueue.size())
}
@Test
fun doTests() {
// start with empty queue
Assert.assertEquals(0, commandQueue.size())
Assertions.assertEquals(0, commandQueue.size())
// add bolus command
commandQueue.bolus(DetailedBolusInfo(), null)
Assert.assertEquals(1, commandQueue.size())
Assertions.assertEquals(1, commandQueue.size())
// add READSTATUS
commandQueue.readStatus("anyString", null)
Assert.assertEquals(2, commandQueue.size())
Assertions.assertEquals(2, commandQueue.size())
// adding another bolus should remove the first one (size still == 2)
commandQueue.bolus(DetailedBolusInfo(), null)
Assert.assertEquals(2, commandQueue.size())
Assertions.assertEquals(2, commandQueue.size())
// clear the queue should reset size
commandQueue.clear()
Assert.assertEquals(0, commandQueue.size())
Assertions.assertEquals(0, commandQueue.size())
// add tempbasal
commandQueue.tempBasalAbsolute(0.0, 30, true, validProfile, PumpSync.TemporaryBasalType.NORMAL, null)
Assert.assertEquals(1, commandQueue.size())
Assertions.assertEquals(1, commandQueue.size())
// add tempbasal percent. it should replace previous TEMPBASAL
commandQueue.tempBasalPercent(0, 30, true, validProfile, PumpSync.TemporaryBasalType.NORMAL, null)
Assert.assertEquals(1, commandQueue.size())
Assertions.assertEquals(1, commandQueue.size())
// cancel tempbasal it should replace previous TEMPBASAL
commandQueue.cancelTempBasal(false, null)
Assert.assertEquals(1, commandQueue.size())
Assertions.assertEquals(1, commandQueue.size())
// add extended bolus
commandQueue.extendedBolus(1.0, 30, null)
Assert.assertEquals(2, commandQueue.size())
Assertions.assertEquals(2, commandQueue.size())
// add extended should remove previous extended setting
commandQueue.extendedBolus(1.0, 30, null)
Assert.assertEquals(2, commandQueue.size())
Assertions.assertEquals(2, commandQueue.size())
// cancel extended bolus should replace previous extended
commandQueue.cancelExtended(null)
Assert.assertEquals(2, commandQueue.size())
Assertions.assertEquals(2, commandQueue.size())
// add setProfile
// TODO: this crash the test
// commandQueue.setProfile(validProfile, null)
// Assert.assertEquals(3, commandQueue.size())
// Assertions.assertEquals(3, commandQueue.size())
// add loadHistory
commandQueue.loadHistory(0.toByte(), null)
Assert.assertEquals(3, commandQueue.size())
Assertions.assertEquals(3, commandQueue.size())
// add loadEvents
commandQueue.loadEvents(null)
Assert.assertEquals(4, commandQueue.size())
Assertions.assertEquals(4, commandQueue.size())
commandQueue.clear()
commandQueue.tempBasalAbsolute(0.0, 30, true, validProfile, PumpSync.TemporaryBasalType.NORMAL, null)
commandQueue.pickup()
Assert.assertEquals(0, commandQueue.size())
Assert.assertNotNull(commandQueue.performing)
Assert.assertEquals(Command.CommandType.TEMPBASAL, commandQueue.performing?.commandType)
Assertions.assertEquals(0, commandQueue.size())
Assertions.assertNotNull(commandQueue.performing)
Assertions.assertEquals(Command.CommandType.TEMPBASAL, commandQueue.performing?.commandType)
commandQueue.resetPerforming()
Assert.assertNull(commandQueue.performing)
Assertions.assertNull(commandQueue.performing)
}
@Test
fun callingCancelAllBolusesClearsQueue() {
// given
Assert.assertEquals(0, commandQueue.size())
Assertions.assertEquals(0, commandQueue.size())
val smb = DetailedBolusInfo()
smb.lastKnownBolusTime = System.currentTimeMillis()
smb.bolusType = DetailedBolusInfo.BolusType.SMB
commandQueue.bolus(smb, null)
commandQueue.bolus(DetailedBolusInfo(), null)
Assert.assertEquals(2, commandQueue.size())
Assertions.assertEquals(2, commandQueue.size())
// when
commandQueue.cancelAllBoluses(null)
// then
Assert.assertEquals(0, commandQueue.size())
Assertions.assertEquals(0, commandQueue.size())
}
@Test
fun smbIsRejectedIfABolusIsQueued() {
// given
Assert.assertEquals(0, commandQueue.size())
Assertions.assertEquals(0, commandQueue.size())
// when
commandQueue.bolus(DetailedBolusInfo(), null)
@ -280,14 +278,14 @@ class CommandQueueImplementationTest : TestBaseWithProfile() {
val queued: Boolean = commandQueue.bolus(smb, null)
// then
Assert.assertFalse(queued)
Assert.assertEquals(commandQueue.size(), 1)
Assertions.assertFalse(queued)
Assertions.assertEquals(commandQueue.size(), 1)
}
@Test
fun smbIsRejectedIfLastKnownBolusIsOutdated() {
// given
Assert.assertEquals(0, commandQueue.size())
Assertions.assertEquals(0, commandQueue.size())
// when
val bolus = DetailedBolusInfo()
@ -296,14 +294,14 @@ class CommandQueueImplementationTest : TestBaseWithProfile() {
val queued: Boolean = commandQueue.bolus(bolus, null)
// then
Assert.assertFalse(queued)
Assert.assertEquals(commandQueue.size(), 0)
Assertions.assertFalse(queued)
Assertions.assertEquals(commandQueue.size(), 0)
}
@Test
fun isCustomCommandRunning() {
// given
Assert.assertEquals(0, commandQueue.size())
Assertions.assertEquals(0, commandQueue.size())
// when
val queued1 = commandQueue.customCommand(CustomCommand1(), null)
@ -311,201 +309,201 @@ class CommandQueueImplementationTest : TestBaseWithProfile() {
commandQueue.pickup()
// then
Assert.assertTrue(queued1)
Assert.assertTrue(queued2)
Assert.assertTrue(commandQueue.isCustomCommandInQueue(CustomCommand1::class.java))
Assert.assertTrue(commandQueue.isCustomCommandInQueue(CustomCommand2::class.java))
Assert.assertFalse(commandQueue.isCustomCommandInQueue(CustomCommand3::class.java))
Assertions.assertTrue(queued1)
Assertions.assertTrue(queued2)
Assertions.assertTrue(commandQueue.isCustomCommandInQueue(CustomCommand1::class.java))
Assertions.assertTrue(commandQueue.isCustomCommandInQueue(CustomCommand2::class.java))
Assertions.assertFalse(commandQueue.isCustomCommandInQueue(CustomCommand3::class.java))
Assert.assertTrue(commandQueue.isCustomCommandRunning(CustomCommand1::class.java))
Assert.assertFalse(commandQueue.isCustomCommandRunning(CustomCommand2::class.java))
Assert.assertFalse(commandQueue.isCustomCommandRunning(CustomCommand3::class.java))
Assertions.assertTrue(commandQueue.isCustomCommandRunning(CustomCommand1::class.java))
Assertions.assertFalse(commandQueue.isCustomCommandRunning(CustomCommand2::class.java))
Assertions.assertFalse(commandQueue.isCustomCommandRunning(CustomCommand3::class.java))
Assert.assertEquals(1, commandQueue.size())
Assertions.assertEquals(1, commandQueue.size())
}
@Test
fun isSetUserOptionsCommandInQueue() {
// given
Assert.assertEquals(0, commandQueue.size())
Assertions.assertEquals(0, commandQueue.size())
// when
commandQueue.setUserOptions(null)
// then
Assert.assertTrue(commandQueue.isLastScheduled(Command.CommandType.SET_USER_SETTINGS))
Assert.assertEquals(1, commandQueue.size())
Assertions.assertTrue(commandQueue.isLastScheduled(Command.CommandType.SET_USER_SETTINGS))
Assertions.assertEquals(1, commandQueue.size())
// next should be ignored
commandQueue.setUserOptions(null)
Assert.assertEquals(1, commandQueue.size())
Assertions.assertEquals(1, commandQueue.size())
}
@Test
fun isLoadEventsCommandInQueue() {
// given
Assert.assertEquals(0, commandQueue.size())
Assertions.assertEquals(0, commandQueue.size())
// when
commandQueue.loadEvents(null)
// then
Assert.assertTrue(commandQueue.isLastScheduled(Command.CommandType.LOAD_EVENTS))
Assert.assertEquals(1, commandQueue.size())
Assertions.assertTrue(commandQueue.isLastScheduled(Command.CommandType.LOAD_EVENTS))
Assertions.assertEquals(1, commandQueue.size())
// next should be ignored
commandQueue.loadEvents(null)
Assert.assertEquals(1, commandQueue.size())
Assertions.assertEquals(1, commandQueue.size())
}
@Test
fun isLoadTDDsCommandInQueue() {
// given
Assert.assertEquals(0, commandQueue.size())
Assertions.assertEquals(0, commandQueue.size())
// when
commandQueue.loadTDDs(null)
// then
Assert.assertEquals(1, commandQueue.size())
Assertions.assertEquals(1, commandQueue.size())
// next should be ignored
commandQueue.loadTDDs(null)
Assert.assertEquals(1, commandQueue.size())
Assertions.assertEquals(1, commandQueue.size())
}
@Test
fun isLoadHistoryCommandInQueue() {
// given
Assert.assertEquals(0, commandQueue.size())
Assertions.assertEquals(0, commandQueue.size())
// when
commandQueue.loadHistory(0, null)
// then
Assert.assertTrue(commandQueue.isLastScheduled(Command.CommandType.LOAD_HISTORY))
Assert.assertEquals(1, commandQueue.size())
Assertions.assertTrue(commandQueue.isLastScheduled(Command.CommandType.LOAD_HISTORY))
Assertions.assertEquals(1, commandQueue.size())
// next should be ignored
commandQueue.loadHistory(0, null)
Assert.assertEquals(1, commandQueue.size())
Assertions.assertEquals(1, commandQueue.size())
}
@Test
fun isProfileSetCommandInQueue() {
// given
Assert.assertEquals(0, commandQueue.size())
Assertions.assertEquals(0, commandQueue.size())
// when
testPumpPlugin.isProfileSet = true
commandQueue.setProfile(validProfile, false, object : Callback() {
override fun run() {
Assert.assertTrue(result.success)
Assert.assertFalse(result.enacted)
Assertions.assertTrue(result.success)
Assertions.assertFalse(result.enacted)
}
})
// then
// the same profile -> ignore
Assert.assertEquals(0, commandQueue.size())
Assertions.assertEquals(0, commandQueue.size())
// different should be added
testPumpPlugin.isProfileSet = false
commandQueue.setProfile(validProfile, false, object : Callback() {
override fun run() {
Assert.assertTrue(result.success)
Assert.assertTrue(result.enacted)
Assertions.assertTrue(result.success)
Assertions.assertTrue(result.enacted)
}
})
Assert.assertEquals(1, commandQueue.size())
Assertions.assertEquals(1, commandQueue.size())
// next should be ignored
commandQueue.setProfile(validProfile, false, object : Callback() {
override fun run() {
Assert.assertTrue(result.success)
Assertions.assertTrue(result.success)
}
})
Assert.assertEquals(1, commandQueue.size())
Assertions.assertEquals(1, commandQueue.size())
testPumpPlugin.isProfileSet = true
}
@Test
fun isStopCommandInQueue() {
// given
Assert.assertEquals(0, commandQueue.size())
Assertions.assertEquals(0, commandQueue.size())
// when
commandQueue.stopPump(null)
// then
Assert.assertTrue(commandQueue.isLastScheduled(Command.CommandType.STOP_PUMP))
Assert.assertEquals(1, commandQueue.size())
Assertions.assertTrue(commandQueue.isLastScheduled(Command.CommandType.STOP_PUMP))
Assertions.assertEquals(1, commandQueue.size())
}
@Test
fun isStarCommandInQueue() {
// given
Assert.assertEquals(0, commandQueue.size())
Assertions.assertEquals(0, commandQueue.size())
// when
commandQueue.startPump(null)
// then
Assert.assertTrue(commandQueue.isLastScheduled(Command.CommandType.START_PUMP))
Assert.assertEquals(1, commandQueue.size())
Assertions.assertTrue(commandQueue.isLastScheduled(Command.CommandType.START_PUMP))
Assertions.assertEquals(1, commandQueue.size())
}
@Test
fun isSetTbrNotificationCommandInQueue() {
// given
Assert.assertEquals(0, commandQueue.size())
Assertions.assertEquals(0, commandQueue.size())
// when
commandQueue.setTBROverNotification(null, true)
// then
Assert.assertTrue(commandQueue.isLastScheduled(Command.CommandType.INSIGHT_SET_TBR_OVER_ALARM))
Assert.assertEquals(1, commandQueue.size())
Assertions.assertTrue(commandQueue.isLastScheduled(Command.CommandType.INSIGHT_SET_TBR_OVER_ALARM))
Assertions.assertEquals(1, commandQueue.size())
}
@Test
fun differentCustomCommandsAllowed() {
// given
Assert.assertEquals(0, commandQueue.size())
Assertions.assertEquals(0, commandQueue.size())
// when
val queued1 = commandQueue.customCommand(CustomCommand1(), null)
val queued2 = commandQueue.customCommand(CustomCommand2(), null)
// then
Assert.assertTrue(queued1)
Assert.assertTrue(queued2)
Assert.assertEquals(2, commandQueue.size())
Assertions.assertTrue(queued1)
Assertions.assertTrue(queued2)
Assertions.assertEquals(2, commandQueue.size())
}
@Test
fun sameCustomCommandNotAllowed() {
// given
Assert.assertEquals(0, commandQueue.size())
Assertions.assertEquals(0, commandQueue.size())
// when
val queued1 = commandQueue.customCommand(CustomCommand1(), null)
val queued2 = commandQueue.customCommand(CustomCommand1(), null)
// then
Assert.assertTrue(queued1)
Assert.assertFalse(queued2)
Assert.assertEquals(1, commandQueue.size())
Assertions.assertTrue(queued1)
Assertions.assertFalse(queued2)
Assertions.assertEquals(1, commandQueue.size())
}
@Test
fun readStatusTwiceIsNotAllowed() {
// given
Assert.assertEquals(0, commandQueue.size())
Assertions.assertEquals(0, commandQueue.size())
// when
val queued1 = commandQueue.readStatus("1", null)
val queued2 = commandQueue.readStatus("2", null)
// then
Assert.assertTrue(queued1)
Assert.assertFalse(queued2)
Assert.assertEquals(1, commandQueue.size())
Assert.assertTrue(commandQueue.statusInQueue())
Assertions.assertTrue(queued1)
Assertions.assertFalse(queued2)
Assertions.assertEquals(1, commandQueue.size())
Assertions.assertTrue(commandQueue.statusInQueue())
}
private class CustomCommand1 : CustomCommand {

View file

@ -17,7 +17,6 @@ import info.nightscout.interfaces.pump.PumpSync
import info.nightscout.interfaces.pump.defs.PumpDescription
import info.nightscout.interfaces.queue.Command
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.shared.sharedPreferences.SP
import org.junit.Assert
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
@ -29,7 +28,6 @@ class QueueThreadTest : TestBaseWithProfile() {
@Mock lateinit var constraintChecker: Constraints
@Mock lateinit var activePlugin: ActivePlugin
@Mock lateinit var sp: SP
@Mock lateinit var powerManager: PowerManager
@Mock lateinit var repository: AppRepository
@Mock lateinit var androidPermission: AndroidPermission

View file

@ -1,11 +1,12 @@
package info.nightscout.core.wizard
package info.nightscout.implementation.wizard
import android.content.Context
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.TestBase
import info.nightscout.androidaps.TestPumpPlugin
import info.nightscout.core.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.core.wizard.BolusWizard
import info.nightscout.implementation.iob.GlucoseStatusProviderImpl
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.aps.AutosensDataStore
import info.nightscout.interfaces.aps.Loop
@ -25,7 +26,6 @@ import org.junit.Assert
import org.junit.jupiter.api.Test
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.`when`
import org.mockito.invocation.InvocationOnMock
class BolusWizardTest : TestBase() {
@ -56,7 +56,7 @@ class BolusWizardTest : TestBase() {
it.loop = loop
it.dateUtil = dateUtil
it.iobCobCalculator = iobCobCalculator
it.glucoseStatusProvider = GlucoseStatusProvider(aapsLogger = aapsLogger, iobCobCalculator = iobCobCalculator, dateUtil = dateUtil)
it.glucoseStatusProvider = GlucoseStatusProviderImpl(aapsLogger = aapsLogger, iobCobCalculator = iobCobCalculator, dateUtil = dateUtil)
}
}
}
@ -66,19 +66,19 @@ class BolusWizardTest : TestBase() {
@Suppress("SameParameterValue")
private fun setupProfile(targetLow: Double, targetHigh: Double, insulinSensitivityFactor: Double, insulinToCarbRatio: Double): Profile {
val profile = Mockito.mock(Profile::class.java)
`when`(profile.getTargetLowMgdl()).thenReturn(targetLow)
`when`(profile.getTargetLowMgdl()).thenReturn(targetHigh)
`when`(profile.getIsfMgdl()).thenReturn(insulinSensitivityFactor)
`when`(profile.getIc()).thenReturn(insulinToCarbRatio)
Mockito.`when`(profile.getTargetLowMgdl()).thenReturn(targetLow)
Mockito.`when`(profile.getTargetLowMgdl()).thenReturn(targetHigh)
Mockito.`when`(profile.getIsfMgdl()).thenReturn(insulinSensitivityFactor)
Mockito.`when`(profile.getIc()).thenReturn(insulinToCarbRatio)
`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL)
`when`(iobCobCalculator.calculateIobFromBolus()).thenReturn(IobTotal(System.currentTimeMillis()))
`when`(iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended()).thenReturn(IobTotal(System.currentTimeMillis()))
`when`(activePlugin.activePump).thenReturn(testPumpPlugin)
Mockito.`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL)
Mockito.`when`(iobCobCalculator.calculateIobFromBolus()).thenReturn(IobTotal(System.currentTimeMillis()))
Mockito.`when`(iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended()).thenReturn(IobTotal(System.currentTimeMillis()))
Mockito.`when`(activePlugin.activePump).thenReturn(testPumpPlugin)
testPumpPlugin.pumpDescription = PumpDescription().also {
it.bolusStep = pumpBolusStep
}
`when`(iobCobCalculator.ads).thenReturn(autosensDataStore)
Mockito.`when`(iobCobCalculator.ads).thenReturn(autosensDataStore)
Mockito.doAnswer { invocation: InvocationOnMock ->
invocation.getArgument<Constraint<Double>>(0)

View file

@ -4,7 +4,6 @@ import android.content.Context
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.annotations.OpenForTesting
import info.nightscout.core.extensions.target
import info.nightscout.core.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.core.utils.MidnightUtils
import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.database.ValueWrapper
@ -14,6 +13,7 @@ import info.nightscout.interfaces.aps.AutosensResult
import info.nightscout.interfaces.aps.DetermineBasalAdapter
import info.nightscout.interfaces.constraints.Constraint
import info.nightscout.interfaces.constraints.Constraints
import info.nightscout.interfaces.iob.GlucoseStatusProvider
import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.plugin.PluginBase

View file

@ -6,7 +6,6 @@ import androidx.preference.SwitchPreference
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.annotations.OpenForTesting
import info.nightscout.core.extensions.target
import info.nightscout.core.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.core.utils.MidnightUtils
import info.nightscout.database.ValueWrapper
import info.nightscout.database.impl.AppRepository
@ -17,6 +16,7 @@ import info.nightscout.interfaces.aps.SMBDefaults
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
import info.nightscout.interfaces.constraints.Constraint
import info.nightscout.interfaces.constraints.Constraints
import info.nightscout.interfaces.iob.GlucoseStatusProvider
import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.plugin.PluginBase

View file

@ -3,12 +3,12 @@ package info.nightscout.plugins.aps.openAPSSMBDynamicISF
import android.content.Context
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.annotations.OpenForTesting
import info.nightscout.core.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.database.impl.AppRepository
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.aps.DetermineBasalAdapter
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
import info.nightscout.interfaces.constraints.Constraints
import info.nightscout.interfaces.iob.GlucoseStatusProvider
import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.ProfileFunction

View file

@ -27,6 +27,8 @@ dependencies {
implementation project(':app-wear-shared:shared')
implementation project(':core:interfaces')
testImplementation project(':implementation')
api "androidx.constraintlayout:constraintlayout:$constraintlayout_version"
api "com.google.android.gms:play-services-location:$play_services_location_version"
}

View file

@ -9,12 +9,12 @@ import info.nightscout.automation.elements.InputString
import info.nightscout.automation.elements.LabelWithElement
import info.nightscout.automation.elements.LayoutBuilder
import info.nightscout.core.extensions.fromConstant
import info.nightscout.core.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.database.entities.TherapyEvent
import info.nightscout.database.entities.UserEntry
import info.nightscout.database.entities.ValueWithUnit
import info.nightscout.database.impl.AppRepository
import info.nightscout.database.impl.transactions.InsertIfNewByTimestampTherapyEventTransaction
import info.nightscout.interfaces.iob.GlucoseStatusProvider
import info.nightscout.interfaces.logging.UserEntryLogger
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.queue.Callback

View file

@ -15,8 +15,8 @@ import info.nightscout.automation.events.EventTriggerChanged
import info.nightscout.automation.events.EventTriggerClone
import info.nightscout.automation.events.EventTriggerRemove
import info.nightscout.automation.services.LastLocationDataContainer
import info.nightscout.core.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.database.impl.AppRepository
import info.nightscout.interfaces.iob.GlucoseStatusProvider
import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.ProfileFunction

View file

@ -7,7 +7,7 @@ import info.nightscout.androidaps.TestBaseWithProfile
import info.nightscout.androidaps.TestPumpPlugin
import info.nightscout.automation.AutomationPlugin
import info.nightscout.automation.services.LastLocationDataContainer
import info.nightscout.core.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.implementation.iob.GlucoseStatusProviderImpl
import info.nightscout.interfaces.aps.AutosensDataStore
import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.plugin.ActivePlugin
@ -51,7 +51,7 @@ open class TriggerTestBase : TestBaseWithProfile() {
it.repository = repository
it.activePlugin = activePlugin
it.iobCobCalculator = iobCobCalculator
it.glucoseStatusProvider = GlucoseStatusProvider(aapsLogger, iobCobCalculator, dateUtil)
it.glucoseStatusProvider = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculator, dateUtil)
it.dateUtil = dateUtil
}
if (it is TriggerBg) {

View file

@ -28,6 +28,8 @@ dependencies {
implementation project(':core:utils')
implementation project(':core:validators')
testImplementation project(':implementation')
api "androidx.appcompat:appcompat:$appcompat_version"
api "com.google.android.material:material:$material_version"

View file

@ -7,13 +7,13 @@ import android.os.Bundle
import dagger.android.HasAndroidInjector
import info.nightscout.core.extensions.durationInMinutes
import info.nightscout.core.extensions.toStringFull
import info.nightscout.core.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.core.iob.round
import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.interfaces.receivers.ReceiverStatusStore
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.aps.Loop
import info.nightscout.interfaces.iob.GlucoseStatusProvider
import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.plugin.PluginBase
import info.nightscout.interfaces.plugin.PluginDescription
@ -21,8 +21,8 @@ import info.nightscout.interfaces.plugin.PluginType
import info.nightscout.interfaces.profile.DefaultValueHelper
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.receivers.Intents
import info.nightscout.interfaces.receivers.ReceiverStatusStore
import info.nightscout.plugins.R
import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData
import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.Event

View file

@ -31,7 +31,6 @@ import info.nightscout.core.extensions.directionToIcon
import info.nightscout.core.extensions.valueToUnitsString
import info.nightscout.core.graph.OverviewData
import info.nightscout.core.iob.displayText
import info.nightscout.core.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.core.profile.ProfileSealed
import info.nightscout.core.ui.UIRunnable
import info.nightscout.core.ui.dialogs.OKDialog
@ -52,6 +51,7 @@ import info.nightscout.interfaces.automation.Automation
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
import info.nightscout.interfaces.constraints.Constraint
import info.nightscout.interfaces.constraints.Constraints
import info.nightscout.interfaces.iob.GlucoseStatusProvider
import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.logging.UserEntryLogger
import info.nightscout.interfaces.nsclient.NSSettingsStatus

View file

@ -10,11 +10,11 @@ import dagger.android.HasAndroidInjector
import info.nightscout.core.extensions.toStringShort
import info.nightscout.core.extensions.valueToUnitsString
import info.nightscout.core.iob.generateCOBString
import info.nightscout.core.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.core.iob.round
import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.NotificationHolder
import info.nightscout.interfaces.iob.GlucoseStatusProvider
import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.plugin.PluginBase

View file

@ -16,7 +16,7 @@ import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
import javax.inject.Inject
class AuthRequest internal constructor(
class AuthRequest(
injector: HasAndroidInjector,
var requester: Sms,
requestText: String,

View file

@ -14,7 +14,6 @@ import info.nightscout.androidaps.annotations.OpenForTesting
import info.nightscout.core.events.EventNewNotification
import info.nightscout.core.extensions.valueToUnitsString
import info.nightscout.core.iob.generateCOBString
import info.nightscout.core.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.core.iob.round
import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.core.utils.receivers.DataWorkerStorage
@ -37,6 +36,7 @@ import info.nightscout.interfaces.XDripBroadcast
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.IobCobCalculator
import info.nightscout.interfaces.logging.UserEntryLogger
import info.nightscout.interfaces.notifications.Notification

View file

@ -9,7 +9,6 @@ import info.nightscout.core.extensions.valueToUnits
import info.nightscout.core.extensions.valueToUnitsString
import info.nightscout.core.graph.data.GlucoseValueDataPoint
import info.nightscout.core.iob.generateCOBString
import info.nightscout.core.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.core.iob.round
import info.nightscout.core.ui.toast.ToastUtils
import info.nightscout.core.utils.fabric.FabricPrivacy
@ -34,6 +33,7 @@ import info.nightscout.interfaces.GlucoseUnit
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.IobCobCalculator
import info.nightscout.interfaces.logging.UserEntryLogger
import info.nightscout.interfaces.nsclient.ProcessedDeviceStatusData

View file

@ -10,7 +10,6 @@ import info.nightscout.core.graph.OverviewData
import info.nightscout.core.iob.combine
import info.nightscout.core.iob.copy
import info.nightscout.core.iob.determineBasalJson
import info.nightscout.core.iob.iobCobCalculator.AutosensDataStoreObject
import info.nightscout.core.iob.plus
import info.nightscout.core.iob.round
import info.nightscout.core.utils.fabric.FabricPrivacy
@ -39,6 +38,7 @@ import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.MidnightTime
import info.nightscout.plugins.R
import info.nightscout.plugins.iob.iobCobCalculator.data.AutosensDataStoreObject
import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.Event

View file

@ -1,4 +1,4 @@
package info.nightscout.core.iob.iobCobCalculator
package info.nightscout.plugins.iob.iobCobCalculator.data
import androidx.collection.LongSparseArray
import androidx.collection.size
@ -310,7 +310,9 @@ class AutosensDataStoreObject : AutosensDataStore {
val previous = bData[i + 1]
val mSecDiff = current.timestamp - previous.timestamp
val adjusted = (mSecDiff - T.mins(5).msecs()) / 1000
aapsLogger.debug(LTag.AUTOSENS) { "Adjusting bucketed data time. Current: ${dateUtil.dateAndTimeAndSecondsString(current.timestamp)} to: ${dateUtil.dateAndTimeAndSecondsString(previous.timestamp + T.mins(5).msecs())} by $adjusted sec" }
aapsLogger.debug(LTag.AUTOSENS) { "Adjusting bucketed data time. Current: ${dateUtil.dateAndTimeAndSecondsString(current.timestamp)} to: ${dateUtil.dateAndTimeAndSecondsString(previous.timestamp + T.mins(
5
).msecs())} by $adjusted sec" }
if (abs(adjusted) > 90) {
// too big adjustment, fallback to non 5 min data
aapsLogger.debug(LTag.AUTOSENS, "Fallback to non 5 min data")

File diff suppressed because it is too large Load diff

View file

@ -6,13 +6,13 @@ import android.view.View
import android.view.ViewGroup
import com.google.common.base.Joiner
import dagger.android.HasAndroidInjector
import info.nightscout.core.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.core.ui.dialogs.OKDialog
import info.nightscout.database.entities.UserEntry.Action
import info.nightscout.database.entities.UserEntry.Sources
import info.nightscout.database.entities.ValueWithUnit
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.XDripBroadcast
import info.nightscout.interfaces.iob.GlucoseStatusProvider
import info.nightscout.interfaces.logging.UserEntryLogger
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction

View file

@ -8,7 +8,6 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.common.base.Joiner
import info.nightscout.core.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.core.ui.dialogs.OKDialog
import info.nightscout.core.ui.toast.ToastUtils
import info.nightscout.core.utils.extensions.formatColor
@ -26,6 +25,7 @@ import info.nightscout.interfaces.Constants.CARBS_FAV3_DEFAULT
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.constraints.Constraint
import info.nightscout.interfaces.constraints.Constraints
import info.nightscout.interfaces.iob.GlucoseStatusProvider
import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.logging.UserEntryLogger
import info.nightscout.interfaces.profile.DefaultValueHelper

View file

@ -11,7 +11,6 @@ import androidx.annotation.StringRes
import com.google.common.base.Joiner
import dagger.android.HasAndroidInjector
import info.nightscout.core.extensions.fromConstant
import info.nightscout.core.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.core.ui.dialogs.OKDialog
import info.nightscout.database.entities.TherapyEvent
import info.nightscout.database.entities.UserEntry
@ -21,6 +20,7 @@ import info.nightscout.database.impl.transactions.InsertIfNewByTimestampTherapyE
import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.Translator
import info.nightscout.interfaces.iob.GlucoseStatusProvider
import info.nightscout.interfaces.logging.UserEntryLogger
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction

View file

@ -17,7 +17,6 @@ import info.nightscout.core.extensions.directionToIcon
import info.nightscout.core.extensions.valueToUnitsString
import info.nightscout.core.graph.OverviewData
import info.nightscout.core.iob.displayText
import info.nightscout.core.iob.iobCobCalculator.GlucoseStatusProvider
import info.nightscout.core.profile.ProfileSealed
import info.nightscout.database.entities.interfaces.end
import info.nightscout.interfaces.Config
@ -26,6 +25,7 @@ import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.aps.Loop
import info.nightscout.interfaces.aps.VariableSensitivityResult
import info.nightscout.interfaces.constraints.Constraints
import info.nightscout.interfaces.iob.GlucoseStatusProvider
import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.Profile