refactor ConstraintObject
This commit is contained in:
parent
49c44a52b9
commit
d939f7ba99
127 changed files with 1818 additions and 1367 deletions
|
@ -2,6 +2,8 @@ package info.nightscout.sharedtests
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import info.nightscout.rx.AapsSchedulers
|
import info.nightscout.rx.AapsSchedulers
|
||||||
|
import info.nightscout.rx.bus.RxBus
|
||||||
|
import info.nightscout.shared.impl.rx.bus.RxBusImpl
|
||||||
import info.nightscout.sharedtests.rx.TestAapsSchedulers
|
import info.nightscout.sharedtests.rx.TestAapsSchedulers
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.extension.ExtendWith
|
import org.junit.jupiter.api.extension.ExtendWith
|
||||||
|
@ -19,11 +21,13 @@ open class TestBase {
|
||||||
|
|
||||||
val aapsLogger = AAPSLoggerTest()
|
val aapsLogger = AAPSLoggerTest()
|
||||||
val aapsSchedulers: AapsSchedulers = TestAapsSchedulers()
|
val aapsSchedulers: AapsSchedulers = TestAapsSchedulers()
|
||||||
|
lateinit var rxBus: RxBus
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
fun setupLocale() {
|
fun setupLocale() {
|
||||||
Locale.setDefault(Locale.ENGLISH)
|
Locale.setDefault(Locale.ENGLISH)
|
||||||
System.setProperty("disableFirebase", "true")
|
System.setProperty("disableFirebase", "true")
|
||||||
|
rxBus = RxBusImpl(aapsSchedulers, aapsLogger)
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("CheckResult")
|
@SuppressLint("CheckResult")
|
||||||
|
|
|
@ -19,10 +19,10 @@ import info.nightscout.interfaces.profile.ProfileFunction
|
||||||
import info.nightscout.interfaces.profile.ProfileStore
|
import info.nightscout.interfaces.profile.ProfileStore
|
||||||
import info.nightscout.interfaces.utils.DecimalFormatter
|
import info.nightscout.interfaces.utils.DecimalFormatter
|
||||||
import info.nightscout.interfaces.utils.HardLimits
|
import info.nightscout.interfaces.utils.HardLimits
|
||||||
import info.nightscout.shared.impl.rx.bus.RxBusImpl
|
|
||||||
import info.nightscout.shared.interfaces.ProfileUtil
|
import info.nightscout.shared.interfaces.ProfileUtil
|
||||||
import info.nightscout.shared.interfaces.ResourceHelper
|
import info.nightscout.shared.interfaces.ResourceHelper
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
|
import info.nightscout.shared.utils.DateUtil
|
||||||
import info.nightscout.shared.utils.DateUtilImpl
|
import info.nightscout.shared.utils.DateUtilImpl
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
|
@ -45,11 +45,10 @@ open class TestBaseWithProfile : TestBase() {
|
||||||
@Mock lateinit var context: Context
|
@Mock lateinit var context: Context
|
||||||
@Mock lateinit var sp: SP
|
@Mock lateinit var sp: SP
|
||||||
|
|
||||||
lateinit var dateUtil: DateUtilImpl
|
lateinit var dateUtil: DateUtil
|
||||||
lateinit var profileUtil: ProfileUtil
|
lateinit var profileUtil: ProfileUtil
|
||||||
lateinit var decimalFormatter: DecimalFormatter
|
lateinit var decimalFormatter: DecimalFormatter
|
||||||
lateinit var hardLimits: HardLimits
|
lateinit var hardLimits: HardLimits
|
||||||
val rxBus = RxBusImpl(aapsSchedulers, aapsLogger)
|
|
||||||
|
|
||||||
val profileInjector = HasAndroidInjector {
|
val profileInjector = HasAndroidInjector {
|
||||||
AndroidInjector {
|
AndroidInjector {
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
package info.nightscout.androidaps
|
package info.nightscout.androidaps
|
||||||
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
//@LargeTest
|
||||||
import androidx.test.filters.LargeTest
|
//@RunWith(AndroidJUnit4::class)
|
||||||
import org.junit.runner.RunWith
|
|
||||||
|
|
||||||
@LargeTest
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
|
||||||
class RealPumpTest {
|
class RealPumpTest {
|
||||||
/*
|
/*
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
package info.nightscout.androidaps
|
package info.nightscout.androidaps
|
||||||
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
//@LargeTest
|
||||||
import androidx.test.filters.LargeTest
|
//@RunWith(AndroidJUnit4::class)
|
||||||
import org.junit.runner.RunWith
|
|
||||||
|
|
||||||
@LargeTest
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
|
||||||
class SetupWizardActivityTest {
|
class SetupWizardActivityTest {
|
||||||
/*
|
/*
|
||||||
@Rule
|
@Rule
|
||||||
|
|
|
@ -52,7 +52,7 @@ import info.nightscout.database.entities.UserEntry.Sources
|
||||||
import info.nightscout.interfaces.AndroidPermission
|
import info.nightscout.interfaces.AndroidPermission
|
||||||
import info.nightscout.interfaces.Config
|
import info.nightscout.interfaces.Config
|
||||||
import info.nightscout.interfaces.aps.Loop
|
import info.nightscout.interfaces.aps.Loop
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.logging.UserEntryLogger
|
import info.nightscout.interfaces.logging.UserEntryLogger
|
||||||
import info.nightscout.interfaces.maintenance.PrefFileListProvider
|
import info.nightscout.interfaces.maintenance.PrefFileListProvider
|
||||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||||
|
@ -96,7 +96,7 @@ class MainActivity : DaggerAppCompatActivityWithResult() {
|
||||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||||
@Inject lateinit var protectionCheck: ProtectionCheck
|
@Inject lateinit var protectionCheck: ProtectionCheck
|
||||||
@Inject lateinit var iconsProvider: IconsProvider
|
@Inject lateinit var iconsProvider: IconsProvider
|
||||||
@Inject lateinit var constraintChecker: Constraints
|
@Inject lateinit var constraintChecker: ConstraintsChecker
|
||||||
@Inject lateinit var signatureVerifierPlugin: SignatureVerifierPlugin
|
@Inject lateinit var signatureVerifierPlugin: SignatureVerifierPlugin
|
||||||
@Inject lateinit var uel: UserEntryLogger
|
@Inject lateinit var uel: UserEntryLogger
|
||||||
@Inject lateinit var profileFunction: ProfileFunction
|
@Inject lateinit var profileFunction: ProfileFunction
|
||||||
|
|
|
@ -38,6 +38,7 @@ import info.nightscout.interfaces.notifications.Notification
|
||||||
import info.nightscout.interfaces.plugin.PluginBase
|
import info.nightscout.interfaces.plugin.PluginBase
|
||||||
import info.nightscout.interfaces.ui.UiInteraction
|
import info.nightscout.interfaces.ui.UiInteraction
|
||||||
import info.nightscout.interfaces.versionChecker.VersionCheckerUtils
|
import info.nightscout.interfaces.versionChecker.VersionCheckerUtils
|
||||||
|
import info.nightscout.plugins.aps.utils.StaticInjector
|
||||||
import info.nightscout.plugins.general.overview.notifications.NotificationStore
|
import info.nightscout.plugins.general.overview.notifications.NotificationStore
|
||||||
import info.nightscout.plugins.general.themes.ThemeSwitcherPlugin
|
import info.nightscout.plugins.general.themes.ThemeSwitcherPlugin
|
||||||
import info.nightscout.rx.logging.AAPSLogger
|
import info.nightscout.rx.logging.AAPSLogger
|
||||||
|
@ -77,7 +78,7 @@ class MainApp : DaggerApplication() {
|
||||||
@Inject lateinit var compatDBHelper: CompatDBHelper
|
@Inject lateinit var compatDBHelper: CompatDBHelper
|
||||||
@Inject lateinit var repository: AppRepository
|
@Inject lateinit var repository: AppRepository
|
||||||
@Inject lateinit var dateUtil: DateUtil
|
@Inject lateinit var dateUtil: DateUtil
|
||||||
@Suppress("unused") @Inject lateinit var staticInjector: info.nightscout.plugins.aps.utils.StaticInjector// TODO avoid , here fake only to initialize
|
@Suppress("unused") @Inject lateinit var staticInjector: StaticInjector// TODO avoid , here fake only to initialize
|
||||||
@Inject lateinit var uel: UserEntryLogger
|
@Inject lateinit var uel: UserEntryLogger
|
||||||
@Inject lateinit var uiInteraction: UiInteraction
|
@Inject lateinit var uiInteraction: UiInteraction
|
||||||
@Inject lateinit var notificationStore: NotificationStore
|
@Inject lateinit var notificationStore: NotificationStore
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
package info.nightscout.androidaps.di
|
|
||||||
|
|
|
@ -8,8 +8,7 @@ import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||||
import info.nightscout.database.impl.AppRepository
|
import info.nightscout.database.impl.AppRepository
|
||||||
import info.nightscout.interfaces.ApsMode
|
import info.nightscout.interfaces.ApsMode
|
||||||
import info.nightscout.interfaces.Config
|
import info.nightscout.interfaces.Config
|
||||||
import info.nightscout.sdk.interfaces.RunningConfiguration
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
|
||||||
import info.nightscout.interfaces.iob.IobCobCalculator
|
import info.nightscout.interfaces.iob.IobCobCalculator
|
||||||
import info.nightscout.interfaces.logging.UserEntryLogger
|
import info.nightscout.interfaces.logging.UserEntryLogger
|
||||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||||
|
@ -20,7 +19,7 @@ import info.nightscout.interfaces.queue.CommandQueue
|
||||||
import info.nightscout.interfaces.receivers.ReceiverStatusStore
|
import info.nightscout.interfaces.receivers.ReceiverStatusStore
|
||||||
import info.nightscout.interfaces.ui.UiInteraction
|
import info.nightscout.interfaces.ui.UiInteraction
|
||||||
import info.nightscout.pump.virtual.VirtualPumpPlugin
|
import info.nightscout.pump.virtual.VirtualPumpPlugin
|
||||||
import info.nightscout.rx.bus.RxBus
|
import info.nightscout.sdk.interfaces.RunningConfiguration
|
||||||
import info.nightscout.shared.interfaces.ResourceHelper
|
import info.nightscout.shared.interfaces.ResourceHelper
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
import info.nightscout.shared.utils.DateUtil
|
import info.nightscout.shared.utils.DateUtil
|
||||||
|
@ -34,8 +33,7 @@ import org.mockito.Mockito.`when`
|
||||||
class LoopPluginTest : TestBase() {
|
class LoopPluginTest : TestBase() {
|
||||||
|
|
||||||
@Mock lateinit var sp: SP
|
@Mock lateinit var sp: SP
|
||||||
private val rxBus: RxBus = RxBus(aapsSchedulers, aapsLogger)
|
@Mock lateinit var constraintChecker: ConstraintsChecker
|
||||||
@Mock lateinit var constraintChecker: Constraints
|
|
||||||
@Mock lateinit var rh: ResourceHelper
|
@Mock lateinit var rh: ResourceHelper
|
||||||
@Mock lateinit var profileFunction: ProfileFunction
|
@Mock lateinit var profileFunction: ProfileFunction
|
||||||
@Mock lateinit var context: Context
|
@Mock lateinit var context: Context
|
||||||
|
|
|
@ -8,7 +8,6 @@ import info.nightscout.interfaces.plugin.ActivePlugin
|
||||||
import info.nightscout.interfaces.protection.ProtectionCheck
|
import info.nightscout.interfaces.protection.ProtectionCheck
|
||||||
import info.nightscout.interfaces.pump.PumpSync
|
import info.nightscout.interfaces.pump.PumpSync
|
||||||
import info.nightscout.interfaces.ui.UiInteraction
|
import info.nightscout.interfaces.ui.UiInteraction
|
||||||
import info.nightscout.rx.bus.RxBus
|
|
||||||
import info.nightscout.shared.interfaces.ResourceHelper
|
import info.nightscout.shared.interfaces.ResourceHelper
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
import info.nightscout.sharedtests.TestBase
|
import info.nightscout.sharedtests.TestBase
|
||||||
|
@ -37,6 +36,6 @@ class ConfigBuilderPluginTest : TestBase() {
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
fun prepareMock() {
|
fun prepareMock() {
|
||||||
configBuilderPlugin = ConfigBuilderPlugin(injector, aapsLogger, rh, sp, RxBus(aapsSchedulers, aapsLogger), activePlugin, uel, pumpSync, protectionCheck, uiInteraction)
|
configBuilderPlugin = ConfigBuilderPlugin(injector, aapsLogger, rh, sp, rxBus, activePlugin, uel, pumpSync, protectionCheck, uiInteraction)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,13 +9,14 @@ import info.nightscout.androidaps.insight.database.InsightDatabase
|
||||||
import info.nightscout.androidaps.insight.database.InsightDatabaseDao
|
import info.nightscout.androidaps.insight.database.InsightDatabaseDao
|
||||||
import info.nightscout.androidaps.insight.database.InsightDbHelper
|
import info.nightscout.androidaps.insight.database.InsightDbHelper
|
||||||
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
|
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.database.impl.AppRepository
|
import info.nightscout.database.impl.AppRepository
|
||||||
import info.nightscout.implementation.iob.GlucoseStatusProviderImpl
|
import info.nightscout.implementation.iob.GlucoseStatusProviderImpl
|
||||||
import info.nightscout.interfaces.ApsMode
|
import info.nightscout.interfaces.ApsMode
|
||||||
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
|
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.Constraint
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
|
||||||
import info.nightscout.interfaces.constraints.Objectives
|
import info.nightscout.interfaces.constraints.Objectives
|
||||||
|
import info.nightscout.interfaces.constraints.PluginConstraints
|
||||||
import info.nightscout.interfaces.maintenance.PrefFileListProvider
|
import info.nightscout.interfaces.maintenance.PrefFileListProvider
|
||||||
import info.nightscout.interfaces.plugin.PluginBase
|
import info.nightscout.interfaces.plugin.PluginBase
|
||||||
import info.nightscout.interfaces.plugin.PluginType
|
import info.nightscout.interfaces.plugin.PluginType
|
||||||
|
@ -74,7 +75,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
||||||
|
|
||||||
private lateinit var danaPump: DanaPump
|
private lateinit var danaPump: DanaPump
|
||||||
private lateinit var insightDbHelper: InsightDbHelper
|
private lateinit var insightDbHelper: InsightDbHelper
|
||||||
private lateinit var constraintChecker: ConstraintsImpl
|
private lateinit var constraintChecker: ConstraintsCheckerImpl
|
||||||
private lateinit var safetyPlugin: SafetyPlugin
|
private lateinit var safetyPlugin: SafetyPlugin
|
||||||
private lateinit var objectivesPlugin: ObjectivesPlugin
|
private lateinit var objectivesPlugin: ObjectivesPlugin
|
||||||
private lateinit var comboPlugin: ComboPlugin
|
private lateinit var comboPlugin: ComboPlugin
|
||||||
|
@ -94,6 +95,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
||||||
if (it is PumpEnactResult) {
|
if (it is PumpEnactResult) {
|
||||||
it.context = context
|
it.context = context
|
||||||
}
|
}
|
||||||
|
if (it is ConstraintObject<*>) {
|
||||||
|
it.aapsLogger = aapsLogger
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +138,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
||||||
`when`(sp.getString(R.string.key_danar_bt_name, "")).thenReturn("")
|
`when`(sp.getString(R.string.key_danar_bt_name, "")).thenReturn("")
|
||||||
|
|
||||||
//SafetyPlugin
|
//SafetyPlugin
|
||||||
constraintChecker = ConstraintsImpl(activePlugin)
|
constraintChecker = ConstraintsCheckerImpl(activePlugin, injector)
|
||||||
|
|
||||||
val glucoseStatusProvider = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculator, dateUtil, decimalFormatter)
|
val glucoseStatusProvider = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculator, dateUtil, decimalFormatter)
|
||||||
|
|
||||||
|
@ -226,7 +230,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
||||||
constraintsPluginsList.add(insightPlugin)
|
constraintsPluginsList.add(insightPlugin)
|
||||||
constraintsPluginsList.add(openAPSAMAPlugin)
|
constraintsPluginsList.add(openAPSAMAPlugin)
|
||||||
constraintsPluginsList.add(openAPSSMBPlugin)
|
constraintsPluginsList.add(openAPSSMBPlugin)
|
||||||
`when`(activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)).thenReturn(constraintsPluginsList)
|
`when`(activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)).thenReturn(constraintsPluginsList)
|
||||||
objectivesPlugin.onStart()
|
objectivesPlugin.onStart()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,7 +300,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
||||||
objectivesPlugin.objectives[Objectives.SMB_OBJECTIVE].startedOn = 0
|
objectivesPlugin.objectives[Objectives.SMB_OBJECTIVE].startedOn = 0
|
||||||
`when`(sp.getBoolean(info.nightscout.plugins.aps.R.string.key_use_smb, false)).thenReturn(false)
|
`when`(sp.getBoolean(info.nightscout.plugins.aps.R.string.key_use_smb, false)).thenReturn(false)
|
||||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.OPEN.name)
|
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.OPEN.name)
|
||||||
// `when`(constraintChecker.isClosedLoopAllowed()).thenReturn(Constraint(true))
|
// `when`(constraintChecker.isClosedLoopAllowed()).thenReturn(ConstraintObject(true))
|
||||||
val c = constraintChecker.isSMBModeEnabled()
|
val c = constraintChecker.isSMBModeEnabled()
|
||||||
assertThat(c.reasonList).hasSize(3) // 2x Safety & Objectives
|
assertThat(c.reasonList).hasSize(3) // 2x Safety & Objectives
|
||||||
assertThat(c.mostLimitedReasonList).hasSize(3) // 2x Safety & Objectives
|
assertThat(c.mostLimitedReasonList).hasSize(3) // 2x Safety & Objectives
|
||||||
|
@ -328,7 +332,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
||||||
val d = constraintChecker.getMaxBasalAllowed(validProfile)
|
val d = constraintChecker.getMaxBasalAllowed(validProfile)
|
||||||
assertThat(d.value()).isWithin(0.01).of(0.8)
|
assertThat(d.value()).isWithin(0.01).of(0.8)
|
||||||
assertThat(d.reasonList).hasSize(3)
|
assertThat(d.reasonList).hasSize(3)
|
||||||
assertThat(d.getMostLimitedReasons(aapsLogger)).isEqualTo("DanaR: Limiting max basal rate to 0.80 U/h because of pump limit")
|
assertThat(d.getMostLimitedReasons()).isEqualTo("DanaR: Limiting max basal rate to 0.80 U/h because of pump limit")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -355,7 +359,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
||||||
val i = constraintChecker.getMaxBasalPercentAllowed(validProfile)
|
val i = constraintChecker.getMaxBasalPercentAllowed(validProfile)
|
||||||
assertThat(i.value()).isEqualTo(200)
|
assertThat(i.value()).isEqualTo(200)
|
||||||
assertThat(i.reasonList).hasSize(6)
|
assertThat(i.reasonList).hasSize(6)
|
||||||
assertThat(i.getMostLimitedReasons(aapsLogger)).isEqualTo("Safety: Limiting max percent rate to 200% because of pump limit")
|
assertThat(i.getMostLimitedReasons()).isEqualTo("Safety: Limiting max percent rate to 200% because of pump limit")
|
||||||
}
|
}
|
||||||
|
|
||||||
// applyBolusConstraints tests
|
// applyBolusConstraints tests
|
||||||
|
@ -382,7 +386,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
||||||
val d = constraintChecker.getMaxBolusAllowed()
|
val d = constraintChecker.getMaxBolusAllowed()
|
||||||
assertThat(d.value()).isWithin(0.01).of(3.0)
|
assertThat(d.value()).isWithin(0.01).of(3.0)
|
||||||
assertThat(d.reasonList).hasSize(4) // 2x Safety & RS & R
|
assertThat(d.reasonList).hasSize(4) // 2x Safety & RS & R
|
||||||
assertThat(d.getMostLimitedReasons(aapsLogger)).isEqualTo("Safety: Limiting bolus to 3.0 U because of max value in preferences")
|
assertThat(d.getMostLimitedReasons()).isEqualTo("Safety: Limiting bolus to 3.0 U because of max value in preferences")
|
||||||
}
|
}
|
||||||
|
|
||||||
// applyCarbsConstraints tests
|
// applyCarbsConstraints tests
|
||||||
|
@ -395,7 +399,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
||||||
val i = constraintChecker.getMaxCarbsAllowed()
|
val i = constraintChecker.getMaxCarbsAllowed()
|
||||||
assertThat(i.value()).isEqualTo(48)
|
assertThat(i.value()).isEqualTo(48)
|
||||||
assertThat(i.reasonList).hasSize(1)
|
assertThat(i.reasonList).hasSize(1)
|
||||||
assertThat(i.getMostLimitedReasons(aapsLogger)).isEqualTo("Safety: Limiting carbs to 48 g because of max value in preferences")
|
assertThat(i.getMostLimitedReasons()).isEqualTo("Safety: Limiting carbs to 48 g because of max value in preferences")
|
||||||
}
|
}
|
||||||
|
|
||||||
// applyMaxIOBConstraints tests
|
// applyMaxIOBConstraints tests
|
||||||
|
@ -412,7 +416,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
||||||
val d = constraintChecker.getMaxIOBAllowed()
|
val d = constraintChecker.getMaxIOBAllowed()
|
||||||
assertThat(d.value()).isWithin(0.01).of(1.5)
|
assertThat(d.value()).isWithin(0.01).of(1.5)
|
||||||
assertThat(d.reasonList).hasSize(2)
|
assertThat(d.reasonList).hasSize(2)
|
||||||
assertThat(d.getMostLimitedReasons(aapsLogger)).isEqualTo("OpenAPSAMA: Limiting IOB to 1.5 U because of max value in preferences")
|
assertThat(d.getMostLimitedReasons()).isEqualTo("OpenAPSAMA: Limiting IOB to 1.5 U because of max value in preferences")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -428,6 +432,6 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
||||||
val d = constraintChecker.getMaxIOBAllowed()
|
val d = constraintChecker.getMaxIOBAllowed()
|
||||||
assertThat(d.value()).isWithin(0.01).of(3.0)
|
assertThat(d.value()).isWithin(0.01).of(3.0)
|
||||||
assertThat(d.reasonList).hasSize(2)
|
assertThat(d.reasonList).hasSize(2)
|
||||||
assertThat(d.getMostLimitedReasons(aapsLogger)).isEqualTo("OpenAPSSMB: Limiting IOB to 3.0 U because of max value in preferences")
|
assertThat(d.getMostLimitedReasons()).isEqualTo("OpenAPSSMB: Limiting IOB to 3.0 U because of max value in preferences")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,12 @@ package info.nightscout.plugins.safety
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import dagger.android.AndroidInjector
|
import dagger.android.AndroidInjector
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.database.impl.AppRepository
|
import info.nightscout.database.impl.AppRepository
|
||||||
import info.nightscout.interfaces.ApsMode
|
import info.nightscout.interfaces.ApsMode
|
||||||
import info.nightscout.interfaces.Constants
|
|
||||||
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
|
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.Constraint
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.iob.GlucoseStatusProvider
|
import info.nightscout.interfaces.iob.GlucoseStatusProvider
|
||||||
import info.nightscout.interfaces.plugin.PluginType
|
import info.nightscout.interfaces.plugin.PluginType
|
||||||
import info.nightscout.interfaces.profiling.Profiler
|
import info.nightscout.interfaces.profiling.Profiler
|
||||||
|
@ -29,7 +29,7 @@ import org.mockito.Mockito.`when`
|
||||||
|
|
||||||
class SafetyPluginTest : TestBaseWithProfile() {
|
class SafetyPluginTest : TestBaseWithProfile() {
|
||||||
|
|
||||||
@Mock lateinit var constraintChecker: Constraints
|
@Mock lateinit var constraintChecker: ConstraintsChecker
|
||||||
@Mock lateinit var virtualPumpPlugin: VirtualPumpPlugin
|
@Mock lateinit var virtualPumpPlugin: VirtualPumpPlugin
|
||||||
@Mock lateinit var glimpPlugin: GlimpPlugin
|
@Mock lateinit var glimpPlugin: GlimpPlugin
|
||||||
@Mock lateinit var profiler: Profiler
|
@Mock lateinit var profiler: Profiler
|
||||||
|
@ -43,7 +43,13 @@ class SafetyPluginTest : TestBaseWithProfile() {
|
||||||
private lateinit var openAPSAMAPlugin: OpenAPSAMAPlugin
|
private lateinit var openAPSAMAPlugin: OpenAPSAMAPlugin
|
||||||
private lateinit var openAPSSMBPlugin: OpenAPSSMBPlugin
|
private lateinit var openAPSSMBPlugin: OpenAPSSMBPlugin
|
||||||
|
|
||||||
private val injector = HasAndroidInjector { AndroidInjector { } }
|
private val injector = HasAndroidInjector {
|
||||||
|
AndroidInjector {
|
||||||
|
if (it is ConstraintObject<*>) {
|
||||||
|
it.aapsLogger = aapsLogger
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
private val pumpDescription = PumpDescription()
|
private val pumpDescription = PumpDescription()
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
|
@ -86,9 +92,8 @@ class SafetyPluginTest : TestBaseWithProfile() {
|
||||||
@Test
|
@Test
|
||||||
fun pumpDescriptionShouldLimitLoopInvocation() {
|
fun pumpDescriptionShouldLimitLoopInvocation() {
|
||||||
pumpDescription.isTempBasalCapable = false
|
pumpDescription.isTempBasalCapable = false
|
||||||
var c = Constraint(true)
|
val c = safetyPlugin.isLoopInvocationAllowed(ConstraintObject(true, injector))
|
||||||
c = safetyPlugin.isLoopInvocationAllowed(c)
|
assertThat(c.getReasons()).isEqualTo("Safety: Pump is not temp basal capable")
|
||||||
assertThat(c.getReasons(aapsLogger)).isEqualTo("Safety: Pump is not temp basal capable")
|
|
||||||
assertThat(c.value()).isFalse()
|
assertThat(c.value()).isFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,47 +101,42 @@ class SafetyPluginTest : TestBaseWithProfile() {
|
||||||
fun disabledEngineeringModeShouldLimitClosedLoop() {
|
fun disabledEngineeringModeShouldLimitClosedLoop() {
|
||||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.CLOSED.name)
|
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.CLOSED.name)
|
||||||
`when`(config.isEngineeringModeOrRelease()).thenReturn(false)
|
`when`(config.isEngineeringModeOrRelease()).thenReturn(false)
|
||||||
var c = Constraint(true)
|
val c = safetyPlugin.isClosedLoopAllowed(ConstraintObject(true, injector))
|
||||||
c = safetyPlugin.isClosedLoopAllowed(c)
|
assertThat(c.getReasons()).contains("Running dev version. Closed loop is disabled.")
|
||||||
assertThat(c.getReasons(aapsLogger)).contains("Running dev version. Closed loop is disabled.")
|
|
||||||
assertThat(c.value()).isFalse()
|
assertThat(c.value()).isFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun setOpenLoopInPreferencesShouldLimitClosedLoop() {
|
fun setOpenLoopInPreferencesShouldLimitClosedLoop() {
|
||||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.OPEN.name)
|
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.OPEN.name)
|
||||||
var c = Constraint(true)
|
val c = safetyPlugin.isClosedLoopAllowed(ConstraintObject(true, injector))
|
||||||
c = safetyPlugin.isClosedLoopAllowed(c)
|
assertThat(c.getReasons()).contains("Closed loop mode disabled in preferences")
|
||||||
assertThat(c.getReasons(aapsLogger)).contains("Closed loop mode disabled in preferences")
|
|
||||||
assertThat(c.value()).isFalse()
|
assertThat(c.value()).isFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun notEnabledSMBInPreferencesDisablesSMB() {
|
fun notEnabledSMBInPreferencesDisablesSMB() {
|
||||||
`when`(sp.getBoolean(info.nightscout.plugins.aps.R.string.key_use_smb, false)).thenReturn(false)
|
`when`(sp.getBoolean(info.nightscout.plugins.aps.R.string.key_use_smb, false)).thenReturn(false)
|
||||||
`when`(constraintChecker.isClosedLoopAllowed(anyObject())).thenReturn(Constraint(true))
|
`when`(constraintChecker.isClosedLoopAllowed(anyObject())).thenReturn(ConstraintObject(true, injector))
|
||||||
var c = Constraint(true)
|
val c = openAPSSMBPlugin.isSMBModeEnabled(ConstraintObject(true, injector))
|
||||||
c = openAPSSMBPlugin.isSMBModeEnabled(c)
|
assertThat(c.getReasons()).contains("SMB disabled in preferences")
|
||||||
assertThat(c.getReasons(aapsLogger)).contains("SMB disabled in preferences")
|
|
||||||
assertThat(c.value()).isFalse()
|
assertThat(c.value()).isFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun openLoopPreventsSMB() {
|
fun openLoopPreventsSMB() {
|
||||||
`when`(sp.getBoolean(info.nightscout.plugins.aps.R.string.key_use_smb, false)).thenReturn(true)
|
`when`(sp.getBoolean(info.nightscout.plugins.aps.R.string.key_use_smb, false)).thenReturn(true)
|
||||||
`when`(constraintChecker.isClosedLoopAllowed(anyObject())).thenReturn(Constraint(false))
|
`when`(constraintChecker.isClosedLoopAllowed()).thenReturn(ConstraintObject(false, injector))
|
||||||
var c = Constraint(true)
|
val c = safetyPlugin.isSMBModeEnabled(ConstraintObject(true, injector))
|
||||||
c = safetyPlugin.isSMBModeEnabled(c)
|
assertThat(c.getReasons()).contains("SMB not allowed in open loop mode")
|
||||||
assertThat(c.getReasons(aapsLogger)).contains("SMB not allowed in open loop mode")
|
|
||||||
assertThat(c.value()).isFalse()
|
assertThat(c.value()).isFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun bgSourceShouldPreventSMBAlways() {
|
fun bgSourceShouldPreventSMBAlways() {
|
||||||
`when`(activePlugin.activeBgSource).thenReturn(glimpPlugin)
|
`when`(activePlugin.activeBgSource).thenReturn(glimpPlugin)
|
||||||
var c = Constraint(true)
|
val c = safetyPlugin.isAdvancedFilteringEnabled(ConstraintObject(true, injector))
|
||||||
c = safetyPlugin.isAdvancedFilteringEnabled(c)
|
assertThat(c.getReasons()).isEqualTo("Safety: SMB always and after carbs disabled because active BG source doesn\\'t support advanced filtering")
|
||||||
assertThat(c.getReasons(aapsLogger)).isEqualTo("Safety: SMB always and after carbs disabled because active BG source doesn\\'t support advanced filtering")
|
|
||||||
assertThat(c.value()).isFalse()
|
assertThat(c.value()).isFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,24 +146,26 @@ class SafetyPluginTest : TestBaseWithProfile() {
|
||||||
`when`(sp.getDouble(info.nightscout.plugins.aps.R.string.key_openapsama_current_basal_safety_multiplier, 4.0)).thenReturn(4.0)
|
`when`(sp.getDouble(info.nightscout.plugins.aps.R.string.key_openapsama_current_basal_safety_multiplier, 4.0)).thenReturn(4.0)
|
||||||
`when`(sp.getDouble(info.nightscout.plugins.aps.R.string.key_openapsama_max_daily_safety_multiplier, 3.0)).thenReturn(3.0)
|
`when`(sp.getDouble(info.nightscout.plugins.aps.R.string.key_openapsama_max_daily_safety_multiplier, 3.0)).thenReturn(3.0)
|
||||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
|
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
|
||||||
val c = Constraint(Constants.REALLYHIGHBASALRATE)
|
val c = ConstraintObject(Double.MAX_VALUE, injector)
|
||||||
safetyPlugin.applyBasalConstraints(c, validProfile)
|
safetyPlugin.applyBasalConstraints(c, validProfile)
|
||||||
assertThat(c.value()).isWithin(0.01).of(2.0)
|
assertThat(c.value()).isWithin(0.01).of(2.0)
|
||||||
assertThat(c.getReasons(aapsLogger)).isEqualTo(
|
assertThat(c.getReasons()).isEqualTo(
|
||||||
"""
|
"""
|
||||||
Safety: Limiting max basal rate to 2.00 U/h because of hard limit
|
Safety: Limiting max basal rate to 2.00 U/h because of hard limit
|
||||||
""".trimIndent())
|
""".trimIndent()
|
||||||
assertThat(c.getMostLimitedReasons(aapsLogger)).isEqualTo("Safety: Limiting max basal rate to 2.00 U/h because of hard limit")
|
)
|
||||||
|
assertThat(c.getMostLimitedReasons()).isEqualTo("Safety: Limiting max basal rate to 2.00 U/h because of hard limit")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun doNotAllowNegativeBasalRate() {
|
fun doNotAllowNegativeBasalRate() {
|
||||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
|
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
|
||||||
val d = Constraint(-0.5)
|
val d = ConstraintObject(-0.5, injector)
|
||||||
safetyPlugin.applyBasalConstraints(d, validProfile)
|
safetyPlugin.applyBasalConstraints(d, validProfile)
|
||||||
assertThat(d.value()).isWithin(0.01).of(0.0)
|
assertThat(d.value()).isWithin(0.01).of(0.0)
|
||||||
assertThat(d.getReasons(aapsLogger)).isEqualTo(
|
assertThat(d.getReasons()).isEqualTo(
|
||||||
"Safety: Limiting max basal rate to 0.00 U/h because of it must be positive value")
|
"Safety: Limiting max basal rate to 0.00 U/h because of it must be positive value"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -173,19 +175,20 @@ class SafetyPluginTest : TestBaseWithProfile() {
|
||||||
`when`(sp.getDouble(info.nightscout.plugins.aps.R.string.key_openapsama_current_basal_safety_multiplier, 4.0)).thenReturn(4.0)
|
`when`(sp.getDouble(info.nightscout.plugins.aps.R.string.key_openapsama_current_basal_safety_multiplier, 4.0)).thenReturn(4.0)
|
||||||
`when`(sp.getDouble(info.nightscout.plugins.aps.R.string.key_openapsama_max_daily_safety_multiplier, 3.0)).thenReturn(3.0)
|
`when`(sp.getDouble(info.nightscout.plugins.aps.R.string.key_openapsama_max_daily_safety_multiplier, 3.0)).thenReturn(3.0)
|
||||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
|
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
|
||||||
val i = Constraint(Constants.REALLYHIGHPERCENTBASALRATE)
|
val i = ConstraintObject(Int.MAX_VALUE, injector)
|
||||||
safetyPlugin.applyBasalPercentConstraints(i, validProfile)
|
safetyPlugin.applyBasalPercentConstraints(i, validProfile)
|
||||||
assertThat(i.value()).isEqualTo(200)
|
assertThat(i.value()).isEqualTo(200)
|
||||||
assertThat(i.getReasons(aapsLogger)).isEqualTo(
|
assertThat(i.getReasons()).isEqualTo(
|
||||||
"""
|
"""
|
||||||
Safety: Percent rate 1111111% recalculated to 11111.11 U/h with current basal 1.00 U/h
|
Safety: Percent rate 2147483647% recalculated to 21474836.47 U/h with current basal 1.00 U/h
|
||||||
Safety: Limiting max basal rate to 2.00 U/h because of hard limit
|
Safety: Limiting max basal rate to 2.00 U/h because of hard limit
|
||||||
Safety: Limiting max percent rate to 200% because of pump limit
|
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
|
Safety: Limiting max basal rate to 500.00 U/h because of pump limit
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
)
|
)
|
||||||
assertThat(i.getMostLimitedReasons(aapsLogger)).isEqualTo(
|
assertThat(i.getMostLimitedReasons()).isEqualTo(
|
||||||
"Safety: Limiting max percent rate to 200% because of pump limit")
|
"Safety: Limiting max percent rate to 200% because of pump limit"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -196,57 +199,58 @@ Safety: Limiting max basal rate to 500.00 U/h because of pump limit
|
||||||
`when`(sp.getDouble(info.nightscout.plugins.aps.R.string.key_openapsama_max_daily_safety_multiplier, 3.0)).thenReturn(3.0)
|
`when`(sp.getDouble(info.nightscout.plugins.aps.R.string.key_openapsama_max_daily_safety_multiplier, 3.0)).thenReturn(3.0)
|
||||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
|
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
|
||||||
openAPSSMBPlugin.setPluginEnabled(PluginType.APS, true)
|
openAPSSMBPlugin.setPluginEnabled(PluginType.APS, true)
|
||||||
val i = Constraint(Constants.REALLYHIGHBASALRATE)
|
val i = ConstraintObject(Double.MAX_VALUE, injector)
|
||||||
openAPSSMBPlugin.applyBasalConstraints(i, validProfile)
|
openAPSSMBPlugin.applyBasalConstraints(i, validProfile)
|
||||||
assertThat(i.value()).isWithin(0.01).of(1.0)
|
assertThat(i.value()).isWithin(0.01).of(1.0)
|
||||||
assertThat(i.getReasons(aapsLogger)).isEqualTo(
|
assertThat(i.getReasons()).isEqualTo(
|
||||||
"""
|
"""
|
||||||
OpenAPSSMB: Limiting max basal rate to 1.00 U/h because of max value in preferences
|
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 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
|
OpenAPSSMB: Limiting max basal rate to 3.00 U/h because of max daily basal multiplier
|
||||||
""".trimIndent())
|
""".trimIndent()
|
||||||
assertThat(i.getMostLimitedReasons(aapsLogger)).isEqualTo("OpenAPSSMB: Limiting max basal rate to 1.00 U/h because of max value in preferences")
|
)
|
||||||
|
assertThat(i.getMostLimitedReasons()).isEqualTo("OpenAPSSMB: Limiting max basal rate to 1.00 U/h because of max value in preferences")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun doNotAllowNegativePercentBasalRate() {
|
fun doNotAllowNegativePercentBasalRate() {
|
||||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
|
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
|
||||||
val i = Constraint(-22)
|
val i = ConstraintObject(-22, injector)
|
||||||
safetyPlugin.applyBasalPercentConstraints(i, validProfile)
|
safetyPlugin.applyBasalPercentConstraints(i, validProfile)
|
||||||
assertThat(i.value()).isEqualTo(0)
|
assertThat(i.value()).isEqualTo(0)
|
||||||
assertThat(i.getReasons(aapsLogger)).isEqualTo(
|
assertThat(i.getReasons()).isEqualTo(
|
||||||
"""
|
"""
|
||||||
Safety: Percent rate -22% recalculated to -0.22 U/h with current basal 1.00 U/h
|
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 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
|
Safety: Limiting max percent rate to 0% because of pump limit
|
||||||
""".trimIndent())
|
""".trimIndent()
|
||||||
assertThat(i.getMostLimitedReasons(aapsLogger)).isEqualTo("Safety: Limiting max percent rate to 0% because of pump limit")
|
)
|
||||||
|
assertThat(i.getMostLimitedReasons()).isEqualTo("Safety: Limiting max percent rate to 0% because of pump limit")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun bolusAmountShouldBeLimited() {
|
fun bolusAmountShouldBeLimited() {
|
||||||
`when`(sp.getDouble(info.nightscout.core.utils.R.string.key_treatmentssafety_maxbolus, 3.0)).thenReturn(3.0)
|
`when`(sp.getDouble(info.nightscout.core.utils.R.string.key_treatmentssafety_maxbolus, 3.0)).thenReturn(3.0)
|
||||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
|
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
|
||||||
var d = Constraint(Constants.REALLYHIGHBOLUS)
|
val d = safetyPlugin.applyBolusConstraints(ConstraintObject(Double.MAX_VALUE, injector))
|
||||||
d = safetyPlugin.applyBolusConstraints(d)
|
|
||||||
assertThat(d.value()).isWithin(0.01).of(3.0)
|
assertThat(d.value()).isWithin(0.01).of(3.0)
|
||||||
assertThat(d.getReasons(aapsLogger)).isEqualTo(
|
assertThat(d.getReasons()).isEqualTo(
|
||||||
"""
|
"""
|
||||||
Safety: Limiting bolus to 3.0 U because of max value in preferences
|
Safety: Limiting bolus to 3.0 U because of max value in preferences
|
||||||
Safety: Limiting bolus to 5.0 U because of hard limit
|
Safety: Limiting bolus to 5.0 U because of hard limit
|
||||||
""".trimIndent())
|
""".trimIndent()
|
||||||
assertThat(d.getMostLimitedReasons(aapsLogger)).isEqualTo("Safety: Limiting bolus to 3.0 U because of max value in preferences")
|
)
|
||||||
|
assertThat(d.getMostLimitedReasons()).isEqualTo("Safety: Limiting bolus to 3.0 U because of max value in preferences")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun doNotAllowNegativeBolusAmount() {
|
fun doNotAllowNegativeBolusAmount() {
|
||||||
`when`(sp.getDouble(info.nightscout.core.utils.R.string.key_treatmentssafety_maxbolus, 3.0)).thenReturn(3.0)
|
`when`(sp.getDouble(info.nightscout.core.utils.R.string.key_treatmentssafety_maxbolus, 3.0)).thenReturn(3.0)
|
||||||
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
|
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
|
||||||
var d = Constraint(-22.0)
|
val d = safetyPlugin.applyBolusConstraints(ConstraintObject(-22.0, injector))
|
||||||
d = safetyPlugin.applyBolusConstraints(d)
|
|
||||||
assertThat(d.value()).isWithin(0.01).of(0.0)
|
assertThat(d.value()).isWithin(0.01).of(0.0)
|
||||||
assertThat(d.getReasons(aapsLogger)).isEqualTo("Safety: Limiting bolus to 0.0 U because of it must be positive value")
|
assertThat(d.getReasons()).isEqualTo("Safety: Limiting bolus to 0.0 U because of it must be positive value")
|
||||||
assertThat(d.getMostLimitedReasons(aapsLogger)).isEqualTo("Safety: Limiting bolus to 0.0 U because of it must be positive value")
|
assertThat(d.getMostLimitedReasons()).isEqualTo("Safety: Limiting bolus to 0.0 U because of it must be positive value")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -255,15 +259,15 @@ Safety: Limiting max basal rate to 500.00 U/h because of pump limit
|
||||||
`when`(sp.getInt(info.nightscout.core.utils.R.string.key_treatmentssafety_maxcarbs, 48)).thenReturn(48)
|
`when`(sp.getInt(info.nightscout.core.utils.R.string.key_treatmentssafety_maxcarbs, 48)).thenReturn(48)
|
||||||
|
|
||||||
// Negative carbs not allowed
|
// Negative carbs not allowed
|
||||||
var i = Constraint(-22)
|
var i: Constraint<Int> = ConstraintObject(-22, injector)
|
||||||
safetyPlugin.applyCarbsConstraints(i)
|
safetyPlugin.applyCarbsConstraints(i)
|
||||||
assertThat(i.value()).isEqualTo(0)
|
assertThat(i.value()).isEqualTo(0)
|
||||||
assertThat(i.getReasons(aapsLogger)).isEqualTo("Safety: Limiting carbs to 0 g because of it must be positive value")
|
assertThat(i.getReasons()).isEqualTo("Safety: Limiting carbs to 0 g because of it must be positive value")
|
||||||
|
|
||||||
// Apply all limits
|
// Apply all limits
|
||||||
i = safetyPlugin.applyCarbsConstraints(Constraint(Constants.REALLYHIGHCARBS))
|
i = safetyPlugin.applyCarbsConstraints(ConstraintObject(Int.MAX_VALUE, injector))
|
||||||
assertThat(i.value()).isEqualTo(48)
|
assertThat(i.value()).isEqualTo(48)
|
||||||
assertThat(i.getReasons(aapsLogger)).isEqualTo("Safety: Limiting carbs to 48 g because of max value in preferences")
|
assertThat(i.getReasons()).isEqualTo("Safety: Limiting carbs to 48 g because of max value in preferences")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -278,24 +282,24 @@ 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("teenage")
|
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("teenage")
|
||||||
|
|
||||||
// Apply all limits
|
// Apply all limits
|
||||||
var d = Constraint(Constants.REALLYHIGHIOB)
|
var d: Constraint<Double> = ConstraintObject(Double.MAX_VALUE, injector)
|
||||||
d = safetyPlugin.applyMaxIOBConstraints(d)
|
d = safetyPlugin.applyMaxIOBConstraints(d)
|
||||||
assertThat(d.value()).isWithin(0.01).of(HardLimits.MAX_IOB_LGS)
|
assertThat(d.value()).isWithin(0.01).of(HardLimits.MAX_IOB_LGS)
|
||||||
assertThat(d.getReasons(aapsLogger)).isEqualTo("Safety: Limiting IOB to 0.0 U because of Low Glucose Suspend")
|
assertThat(d.getReasons()).isEqualTo("Safety: Limiting IOB to 0.0 U because of Low Glucose Suspend")
|
||||||
assertThat(d.getMostLimitedReasons(aapsLogger)).isEqualTo("Safety: Limiting IOB to 0.0 U because of Low Glucose Suspend")
|
assertThat(d.getMostLimitedReasons()).isEqualTo("Safety: Limiting IOB to 0.0 U because of Low Glucose Suspend")
|
||||||
|
|
||||||
// Apply all limits
|
// Apply all limits
|
||||||
d = Constraint(Constants.REALLYHIGHIOB)
|
d = ConstraintObject(Double.MAX_VALUE, injector)
|
||||||
val a = openAPSAMAPlugin.applyMaxIOBConstraints(d)
|
val a = openAPSAMAPlugin.applyMaxIOBConstraints(d)
|
||||||
assertThat(a.value()).isWithin(0.01).of(1.5)
|
assertThat(a.value()).isWithin(0.01).of(1.5)
|
||||||
assertThat(d.getReasons(aapsLogger)).isEqualTo("OpenAPSAMA: Limiting IOB to 1.5 U because of max value in preferences\nOpenAPSAMA: Limiting IOB to 7.0 U because of hard limit")
|
assertThat(d.getReasons()).isEqualTo("OpenAPSAMA: Limiting IOB to 1.5 U because of max value in preferences\nOpenAPSAMA: Limiting IOB to 7.0 U because of hard limit")
|
||||||
assertThat(d.getMostLimitedReasons(aapsLogger)).isEqualTo("OpenAPSAMA: Limiting IOB to 1.5 U because of max value in preferences")
|
assertThat(d.getMostLimitedReasons()).isEqualTo("OpenAPSAMA: Limiting IOB to 1.5 U because of max value in preferences")
|
||||||
|
|
||||||
// Apply all limits
|
// Apply all limits
|
||||||
d = Constraint(Constants.REALLYHIGHIOB)
|
d = ConstraintObject(Double.MAX_VALUE, injector)
|
||||||
val s = openAPSSMBPlugin.applyMaxIOBConstraints(d)
|
val s = openAPSSMBPlugin.applyMaxIOBConstraints(d)
|
||||||
assertThat(s.value()).isWithin(0.01).of(3.0)
|
assertThat(s.value()).isWithin(0.01).of(3.0)
|
||||||
assertThat(d.getReasons(aapsLogger)).isEqualTo("OpenAPSSMB: Limiting IOB to 3.0 U because of max value in preferences\nOpenAPSSMB: Limiting IOB to 22.0 U because of hard limit")
|
assertThat(d.getReasons()).isEqualTo("OpenAPSSMB: Limiting IOB to 3.0 U because of max value in preferences\nOpenAPSSMB: Limiting IOB to 22.0 U because of hard limit")
|
||||||
assertThat(d.getMostLimitedReasons(aapsLogger)).isEqualTo("OpenAPSSMB: Limiting IOB to 3.0 U because of max value in preferences")
|
assertThat(d.getMostLimitedReasons()).isEqualTo("OpenAPSSMB: Limiting IOB to 3.0 U because of max value in preferences")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,6 @@ object Constants {
|
||||||
const val MMOLL_TO_MGDL = 18.0 // 18.0182;
|
const val MMOLL_TO_MGDL = 18.0 // 18.0182;
|
||||||
const val MGDL_TO_MMOLL = 1 / MMOLL_TO_MGDL
|
const val MGDL_TO_MMOLL = 1 / MMOLL_TO_MGDL
|
||||||
const val defaultDIA = 5.0
|
const val defaultDIA = 5.0
|
||||||
const val REALLYHIGHBASALRATE = 1111111.0
|
|
||||||
const val REALLYHIGHPERCENTBASALRATE = 1111111
|
|
||||||
const val REALLYHIGHBOLUS = 1111111.0
|
|
||||||
const val REALLYHIGHCARBS = 1111111
|
|
||||||
const val REALLYHIGHIOB = 1111111.0
|
|
||||||
const val notificationID = 556677
|
const val notificationID = 556677
|
||||||
|
|
||||||
// SMS COMMUNICATOR
|
// SMS COMMUNICATOR
|
||||||
|
|
|
@ -1,115 +1,18 @@
|
||||||
package info.nightscout.interfaces.constraints
|
package info.nightscout.interfaces.constraints
|
||||||
|
|
||||||
import info.nightscout.rx.logging.AAPSLogger
|
interface Constraint<T : Comparable<T>> {
|
||||||
import info.nightscout.rx.logging.LTag
|
|
||||||
|
|
||||||
class Constraint<T : Comparable<T>>(private var value: T) {
|
|
||||||
|
|
||||||
private var originalValue: T
|
|
||||||
private val reasons: MutableList<String> = ArrayList()
|
|
||||||
private val mostLimiting: MutableList<String> = ArrayList()
|
|
||||||
fun value(): T {
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
|
|
||||||
fun originalValue(): T {
|
|
||||||
return originalValue
|
|
||||||
}
|
|
||||||
|
|
||||||
fun set(aapsLogger: AAPSLogger, value: T): Constraint<T> {
|
|
||||||
this.value = value
|
|
||||||
originalValue = value
|
|
||||||
aapsLogger.debug(LTag.CONSTRAINTS, "Setting value $value")
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun set(aapsLogger: AAPSLogger, value: T, reason: String, from: Any): Constraint<T> {
|
|
||||||
aapsLogger.debug(LTag.CONSTRAINTS, "Setting value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]")
|
|
||||||
this.value = value
|
|
||||||
addReason(reason, from)
|
|
||||||
addMostLimingReason(reason, from)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setIfDifferent(aapsLogger: AAPSLogger, value: T, reason: String, from: Any): Constraint<T> {
|
|
||||||
if (this.value != value) {
|
|
||||||
aapsLogger.debug(LTag.CONSTRAINTS, "Setting because of different value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]")
|
|
||||||
this.value = value
|
|
||||||
addReason(reason, from)
|
|
||||||
addMostLimingReason(reason, from)
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setIfSmaller(aapsLogger: AAPSLogger, value: T, reason: String, from: Any): Constraint<T> {
|
|
||||||
if (value < this.value) {
|
|
||||||
aapsLogger.debug(LTag.CONSTRAINTS, "Setting because of smaller value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]")
|
|
||||||
this.value = value
|
|
||||||
mostLimiting.clear()
|
|
||||||
addMostLimingReason(reason, from)
|
|
||||||
}
|
|
||||||
if (value < originalValue) {
|
|
||||||
addReason(reason, from)
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setIfGreater(aapsLogger: AAPSLogger, value: T, reason: String, from: Any): Constraint<T> {
|
|
||||||
if (value > this.value) {
|
|
||||||
aapsLogger.debug(LTag.CONSTRAINTS, "Setting because of greater value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]")
|
|
||||||
this.value = value
|
|
||||||
mostLimiting.clear()
|
|
||||||
addMostLimingReason(reason, from)
|
|
||||||
}
|
|
||||||
if (value > originalValue) {
|
|
||||||
addReason(reason, from)
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun translateFrom(from: Any): String {
|
|
||||||
return from.javaClass.simpleName.replace("Plugin", "")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addReason(reason: String, from: Any) {
|
|
||||||
reasons.add(translateFrom(from) + ": " + reason)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun addMostLimingReason(reason: String, from: Any) {
|
|
||||||
mostLimiting.add(translateFrom(from) + ": " + reason)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getReasons(aapsLogger: AAPSLogger): String {
|
|
||||||
val sb = StringBuilder()
|
|
||||||
for ((count, r) in reasons.withIndex()) {
|
|
||||||
if (count != 0) sb.append("\n")
|
|
||||||
sb.append(r)
|
|
||||||
}
|
|
||||||
aapsLogger.debug(LTag.CONSTRAINTS, "Limiting original value: $originalValue to $value. Reason: $sb")
|
|
||||||
return sb.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
fun value(): T
|
||||||
|
fun originalValue(): T
|
||||||
|
fun set(value: T): Constraint<T>
|
||||||
|
fun set(value: T, reason: String, from: Any): Constraint<T>
|
||||||
|
fun setIfDifferent(value: T, reason: String, from: Any): Constraint<T>
|
||||||
|
fun setIfSmaller(value: T, reason: String, from: Any): Constraint<T>
|
||||||
|
fun setIfGreater(value: T, reason: String, from: Any): Constraint<T>
|
||||||
|
fun addReason(reason: String, from: Any)
|
||||||
|
fun getReasons(): String
|
||||||
val reasonList: List<String>
|
val reasonList: List<String>
|
||||||
get() = reasons
|
fun getMostLimitedReasons(): String
|
||||||
|
|
||||||
fun getMostLimitedReasons(aapsLogger: AAPSLogger): String {
|
|
||||||
val sb = StringBuilder()
|
|
||||||
for ((count, r) in mostLimiting.withIndex()) {
|
|
||||||
if (count != 0) sb.append("\n")
|
|
||||||
sb.append(r)
|
|
||||||
}
|
|
||||||
aapsLogger.debug(LTag.CONSTRAINTS, "Limiting original value: $originalValue to $value. Reason: $sb")
|
|
||||||
return sb.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
val mostLimitedReasonList: List<String>
|
val mostLimitedReasonList: List<String>
|
||||||
get() = mostLimiting
|
fun copyReasons(another: Constraint<*>)
|
||||||
|
|
||||||
fun copyReasons(another: Constraint<*>) {
|
|
||||||
reasons.addAll(another.reasonList)
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
originalValue = value
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,58 +0,0 @@
|
||||||
package info.nightscout.interfaces.constraints
|
|
||||||
|
|
||||||
import info.nightscout.interfaces.Constants
|
|
||||||
import info.nightscout.interfaces.profile.Profile
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constraints interface
|
|
||||||
*
|
|
||||||
* Every function has a param from previous chained call
|
|
||||||
* Function can limit the value even more and add another reason of restriction
|
|
||||||
*
|
|
||||||
* see [info.nightscout.plugins.constraints.ConstraintsImpl]
|
|
||||||
* which iterates over all registered plugins with [Constraints] implemented
|
|
||||||
*
|
|
||||||
* @return updated parameter
|
|
||||||
*/
|
|
||||||
interface Constraints {
|
|
||||||
|
|
||||||
fun isLoopInvocationAllowed(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
|
||||||
fun isClosedLoopAllowed(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
|
||||||
fun isLgsAllowed(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
|
||||||
fun isAutosensModeEnabled(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
|
||||||
fun isSMBModeEnabled(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
|
||||||
fun isDynIsfModeEnabled(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
|
||||||
fun isUAMEnabled(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
|
||||||
fun isAdvancedFilteringEnabled(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
|
||||||
fun isSuperBolusEnabled(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
|
||||||
fun isAutomationEnabled(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
|
||||||
fun applyBasalConstraints(absoluteRate: Constraint<Double>, profile: Profile): Constraint<Double> = absoluteRate
|
|
||||||
fun applyBasalPercentConstraints(percentRate: Constraint<Int>, profile: Profile): Constraint<Int> = percentRate
|
|
||||||
fun applyBolusConstraints(insulin: Constraint<Double>): Constraint<Double> = insulin
|
|
||||||
fun applyExtendedBolusConstraints(insulin: Constraint<Double>): Constraint<Double> = insulin
|
|
||||||
fun applyCarbsConstraints(carbs: Constraint<Int>): Constraint<Int> = carbs
|
|
||||||
fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> = maxIob
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Determine max values by walking through all constraints
|
|
||||||
*/
|
|
||||||
fun getMaxBasalAllowed(profile: Profile): Constraint<Double> =
|
|
||||||
applyBasalConstraints(Constraint(Constants.REALLYHIGHBASALRATE), profile)
|
|
||||||
|
|
||||||
fun getMaxBasalPercentAllowed(profile: Profile): Constraint<Int> =
|
|
||||||
applyBasalPercentConstraints(Constraint(Constants.REALLYHIGHPERCENTBASALRATE), profile)
|
|
||||||
|
|
||||||
fun getMaxBolusAllowed(): Constraint<Double> =
|
|
||||||
applyBolusConstraints(Constraint(Constants.REALLYHIGHBOLUS))
|
|
||||||
|
|
||||||
fun getMaxExtendedBolusAllowed(): Constraint<Double> =
|
|
||||||
applyExtendedBolusConstraints(Constraint(Constants.REALLYHIGHBOLUS))
|
|
||||||
|
|
||||||
fun getMaxCarbsAllowed(): Constraint<Int> =
|
|
||||||
applyCarbsConstraints(Constraint(Constants.REALLYHIGHCARBS))
|
|
||||||
|
|
||||||
fun getMaxIOBAllowed(): Constraint<Double> =
|
|
||||||
applyMaxIOBConstraints(Constraint(Constants.REALLYHIGHIOB))
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package info.nightscout.interfaces.constraints
|
||||||
|
|
||||||
|
import info.nightscout.interfaces.profile.Profile
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constraints interface
|
||||||
|
*
|
||||||
|
* Every function has a param from previous chained call
|
||||||
|
* Function can limit the value even more and add another reason of restriction
|
||||||
|
*
|
||||||
|
* see [info.nightscout.plugins.constraints.ConstraintsCheckerImpl]
|
||||||
|
* which iterates over all registered plugins with [ConstraintsChecker] implemented
|
||||||
|
*/
|
||||||
|
interface ConstraintsChecker : PluginConstraints {
|
||||||
|
|
||||||
|
fun isLoopInvocationAllowed(): Constraint<Boolean>
|
||||||
|
fun isClosedLoopAllowed(): Constraint<Boolean>
|
||||||
|
fun isLgsAllowed(): Constraint<Boolean>
|
||||||
|
fun isAutosensModeEnabled(): Constraint<Boolean>
|
||||||
|
fun isSMBModeEnabled(): Constraint<Boolean>
|
||||||
|
fun isDynIsfModeEnabled(): Constraint<Boolean>
|
||||||
|
fun isUAMEnabled(): Constraint<Boolean>
|
||||||
|
fun isAdvancedFilteringEnabled(): Constraint<Boolean>
|
||||||
|
fun isSuperBolusEnabled(): Constraint<Boolean>
|
||||||
|
fun isAutomationEnabled(): Constraint<Boolean>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine max values by walking through all constraints
|
||||||
|
*/
|
||||||
|
fun getMaxBasalAllowed(profile: Profile): Constraint<Double>
|
||||||
|
fun getMaxBasalPercentAllowed(profile: Profile): Constraint<Int>
|
||||||
|
fun getMaxBolusAllowed(): Constraint<Double>
|
||||||
|
fun getMaxExtendedBolusAllowed(): Constraint<Double>
|
||||||
|
fun getMaxCarbsAllowed(): Constraint<Int>
|
||||||
|
fun getMaxIOBAllowed(): Constraint<Double>
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package info.nightscout.interfaces.constraints
|
||||||
|
|
||||||
|
import info.nightscout.interfaces.profile.Profile
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PluginConstraints interface
|
||||||
|
*
|
||||||
|
* Allows to every plugin implement own constraints
|
||||||
|
*/
|
||||||
|
interface PluginConstraints {
|
||||||
|
|
||||||
|
fun isLoopInvocationAllowed(value: Constraint<Boolean>): Constraint<Boolean> = value
|
||||||
|
fun isClosedLoopAllowed(value: Constraint<Boolean>): Constraint<Boolean> = value
|
||||||
|
fun isLgsAllowed(value: Constraint<Boolean>): Constraint<Boolean> = value
|
||||||
|
fun isAutosensModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> = value
|
||||||
|
fun isSMBModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> = value
|
||||||
|
fun isDynIsfModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> = value
|
||||||
|
fun isUAMEnabled(value: Constraint<Boolean>): Constraint<Boolean> = value
|
||||||
|
fun isAdvancedFilteringEnabled(value: Constraint<Boolean>): Constraint<Boolean> = value
|
||||||
|
fun isSuperBolusEnabled(value: Constraint<Boolean>): Constraint<Boolean> = value
|
||||||
|
fun isAutomationEnabled(value: Constraint<Boolean>): Constraint<Boolean> = value
|
||||||
|
fun applyBasalConstraints(absoluteRate: Constraint<Double>, profile: Profile): Constraint<Double> = absoluteRate
|
||||||
|
fun applyBasalPercentConstraints(percentRate: Constraint<Int>, profile: Profile): Constraint<Int> = percentRate
|
||||||
|
fun applyBolusConstraints(insulin: Constraint<Double>): Constraint<Double> = insulin
|
||||||
|
fun applyExtendedBolusConstraints(insulin: Constraint<Double>): Constraint<Double> = insulin
|
||||||
|
fun applyCarbsConstraints(carbs: Constraint<Int>): Constraint<Int> = carbs
|
||||||
|
fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> = maxIob
|
||||||
|
}
|
|
@ -20,6 +20,7 @@ dependencies {
|
||||||
implementation project(':core:utils')
|
implementation project(':core:utils')
|
||||||
|
|
||||||
testImplementation project(':app-wear-shared:shared-tests')
|
testImplementation project(':app-wear-shared:shared-tests')
|
||||||
|
testImplementation project(':app-wear-shared:shared-impl')
|
||||||
|
|
||||||
api "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
api "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
package info.nightscout.core.constraints
|
||||||
|
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.interfaces.constraints.Constraint
|
||||||
|
import info.nightscout.rx.logging.AAPSLogger
|
||||||
|
import info.nightscout.rx.logging.LTag
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class ConstraintObject<T : Comparable<T>>(private var value: T, injector: HasAndroidInjector) : Constraint<T> {
|
||||||
|
|
||||||
|
@Inject lateinit var aapsLogger: AAPSLogger
|
||||||
|
|
||||||
|
private var originalValue: T
|
||||||
|
private val reasons: MutableList<String> = ArrayList()
|
||||||
|
private val mostLimiting: MutableList<String> = ArrayList()
|
||||||
|
override fun value(): T {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun originalValue(): T {
|
||||||
|
return originalValue
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun set(value: T): Constraint<T> {
|
||||||
|
this.value = value
|
||||||
|
originalValue = value
|
||||||
|
aapsLogger.debug(LTag.CONSTRAINTS, "Setting value $value")
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun set(value: T, reason: String, from: Any): Constraint<T> {
|
||||||
|
aapsLogger.debug(LTag.CONSTRAINTS, "Setting value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]")
|
||||||
|
this.value = value
|
||||||
|
addReason(reason, from)
|
||||||
|
addMostLimingReason(reason, from)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setIfDifferent(value: T, reason: String, from: Any): Constraint<T> {
|
||||||
|
if (this.value != value) {
|
||||||
|
aapsLogger.debug(LTag.CONSTRAINTS, "Setting because of different value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]")
|
||||||
|
this.value = value
|
||||||
|
addReason(reason, from)
|
||||||
|
addMostLimingReason(reason, from)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setIfSmaller(value: T, reason: String, from: Any): Constraint<T> {
|
||||||
|
if (value < this.value) {
|
||||||
|
aapsLogger.debug(LTag.CONSTRAINTS, "Setting because of smaller value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]")
|
||||||
|
this.value = value
|
||||||
|
mostLimiting.clear()
|
||||||
|
addMostLimingReason(reason, from)
|
||||||
|
}
|
||||||
|
if (value < originalValue) {
|
||||||
|
addReason(reason, from)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setIfGreater(value: T, reason: String, from: Any): Constraint<T> {
|
||||||
|
if (value > this.value) {
|
||||||
|
aapsLogger.debug(LTag.CONSTRAINTS, "Setting because of greater value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]")
|
||||||
|
this.value = value
|
||||||
|
mostLimiting.clear()
|
||||||
|
addMostLimingReason(reason, from)
|
||||||
|
}
|
||||||
|
if (value > originalValue) {
|
||||||
|
addReason(reason, from)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun translateFrom(from: Any): String {
|
||||||
|
return from.javaClass.simpleName.replace("Plugin", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addReason(reason: String, from: Any) {
|
||||||
|
reasons.add(translateFrom(from) + ": " + reason)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addMostLimingReason(reason: String, from: Any) {
|
||||||
|
mostLimiting.add(translateFrom(from) + ": " + reason)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getReasons(): String {
|
||||||
|
val sb = StringBuilder()
|
||||||
|
for ((count, r) in reasons.withIndex()) {
|
||||||
|
if (count != 0) sb.append("\n")
|
||||||
|
sb.append(r)
|
||||||
|
}
|
||||||
|
aapsLogger.debug(LTag.CONSTRAINTS, "Limiting original value: $originalValue to $value. Reason: $sb")
|
||||||
|
return sb.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
override val reasonList: List<String>
|
||||||
|
get() = reasons
|
||||||
|
|
||||||
|
override fun getMostLimitedReasons(): String {
|
||||||
|
val sb = StringBuilder()
|
||||||
|
for ((count, r) in mostLimiting.withIndex()) {
|
||||||
|
if (count != 0) sb.append("\n")
|
||||||
|
sb.append(r)
|
||||||
|
}
|
||||||
|
aapsLogger.debug(LTag.CONSTRAINTS, "Limiting original value: $originalValue to $value. Reason: $sb")
|
||||||
|
return sb.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
override val mostLimitedReasonList: List<String>
|
||||||
|
get() = mostLimiting
|
||||||
|
|
||||||
|
override fun copyReasons(another: Constraint<*>) {
|
||||||
|
reasons.addAll(another.reasonList)
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
injector.androidInjector().inject(this)
|
||||||
|
originalValue = value
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ import android.content.Context
|
||||||
import android.text.Spanned
|
import android.text.Spanned
|
||||||
import com.google.common.base.Joiner
|
import com.google.common.base.Joiner
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.core.extensions.highValueToUnitsToString
|
import info.nightscout.core.extensions.highValueToUnitsToString
|
||||||
import info.nightscout.core.extensions.lowValueToUnitsToString
|
import info.nightscout.core.extensions.lowValueToUnitsToString
|
||||||
import info.nightscout.core.iob.round
|
import info.nightscout.core.iob.round
|
||||||
|
@ -19,8 +20,7 @@ import info.nightscout.database.entities.ValueWithUnit
|
||||||
import info.nightscout.interfaces.Config
|
import info.nightscout.interfaces.Config
|
||||||
import info.nightscout.interfaces.aps.Loop
|
import info.nightscout.interfaces.aps.Loop
|
||||||
import info.nightscout.interfaces.automation.Automation
|
import info.nightscout.interfaces.automation.Automation
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
|
||||||
import info.nightscout.interfaces.db.PersistenceLayer
|
import info.nightscout.interfaces.db.PersistenceLayer
|
||||||
import info.nightscout.interfaces.iob.GlucoseStatus
|
import info.nightscout.interfaces.iob.GlucoseStatus
|
||||||
import info.nightscout.interfaces.iob.GlucoseStatusProvider
|
import info.nightscout.interfaces.iob.GlucoseStatusProvider
|
||||||
|
@ -63,7 +63,7 @@ class BolusWizard @Inject constructor(
|
||||||
@Inject lateinit var sp: SP
|
@Inject lateinit var sp: SP
|
||||||
@Inject lateinit var profileFunction: ProfileFunction
|
@Inject lateinit var profileFunction: ProfileFunction
|
||||||
@Inject lateinit var profileUtil: ProfileUtil
|
@Inject lateinit var profileUtil: ProfileUtil
|
||||||
@Inject lateinit var constraintChecker: Constraints
|
@Inject lateinit var constraintChecker: ConstraintsChecker
|
||||||
@Inject lateinit var activePlugin: ActivePlugin
|
@Inject lateinit var activePlugin: ActivePlugin
|
||||||
@Inject lateinit var commandQueue: CommandQueue
|
@Inject lateinit var commandQueue: CommandQueue
|
||||||
@Inject lateinit var loop: Loop
|
@Inject lateinit var loop: Loop
|
||||||
|
@ -273,7 +273,7 @@ class BolusWizard @Inject constructor(
|
||||||
val bolusStep = activePlugin.activePump.pumpDescription.bolusStep
|
val bolusStep = activePlugin.activePump.pumpDescription.bolusStep
|
||||||
calculatedTotalInsulin = Round.roundTo(calculatedTotalInsulin, bolusStep)
|
calculatedTotalInsulin = Round.roundTo(calculatedTotalInsulin, bolusStep)
|
||||||
|
|
||||||
insulinAfterConstraints = constraintChecker.applyBolusConstraints(Constraint(calculatedTotalInsulin)).value()
|
insulinAfterConstraints = constraintChecker.applyBolusConstraints(ConstraintObject(calculatedTotalInsulin, injector)).value()
|
||||||
|
|
||||||
aapsLogger.debug(this.toString())
|
aapsLogger.debug(this.toString())
|
||||||
return this
|
return this
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package info.nightscout.core.data
|
package info.nightscout.core.data
|
||||||
|
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import dagger.android.AndroidInjector
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.sharedtests.TestBase
|
import info.nightscout.sharedtests.TestBase
|
||||||
import org.junit.jupiter.api.Assertions
|
import org.junit.jupiter.api.Assertions
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
|
@ -11,41 +13,49 @@ import org.junit.jupiter.api.Test
|
||||||
*/
|
*/
|
||||||
class ConstraintTest : TestBase() {
|
class ConstraintTest : TestBase() {
|
||||||
|
|
||||||
|
private val injector = HasAndroidInjector {
|
||||||
|
AndroidInjector {
|
||||||
|
if (it is ConstraintObject<*>) {
|
||||||
|
it.aapsLogger = aapsLogger
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test fun doTests() {
|
@Test fun doTests() {
|
||||||
val b = Constraint(true)
|
val b = ConstraintObject(true, injector)
|
||||||
Assertions.assertEquals(true, b.value())
|
Assertions.assertEquals(true, b.value())
|
||||||
Assertions.assertEquals("", b.getReasons(aapsLogger))
|
Assertions.assertEquals("", b.getReasons())
|
||||||
Assertions.assertEquals("", b.getMostLimitedReasons(aapsLogger))
|
Assertions.assertEquals("", b.getMostLimitedReasons())
|
||||||
b.set(aapsLogger, false)
|
b.set(false)
|
||||||
Assertions.assertEquals(false, b.value())
|
Assertions.assertEquals(false, b.value())
|
||||||
Assertions.assertEquals("", b.getReasons(aapsLogger))
|
Assertions.assertEquals("", b.getReasons())
|
||||||
Assertions.assertEquals("", b.getMostLimitedReasons(aapsLogger))
|
Assertions.assertEquals("", b.getMostLimitedReasons())
|
||||||
b.set(aapsLogger, true, "Set true", this)
|
b.set(true, "Set true", this)
|
||||||
Assertions.assertEquals(true, b.value())
|
Assertions.assertEquals(true, b.value())
|
||||||
Assertions.assertEquals("ConstraintTest: Set true", b.getReasons(aapsLogger))
|
Assertions.assertEquals("ConstraintTest: Set true", b.getReasons())
|
||||||
Assertions.assertEquals("ConstraintTest: Set true", b.getMostLimitedReasons(aapsLogger))
|
Assertions.assertEquals("ConstraintTest: Set true", b.getMostLimitedReasons())
|
||||||
b.set(aapsLogger, false, "Set false", this)
|
b.set(false, "Set false", this)
|
||||||
Assertions.assertEquals(false, b.value())
|
Assertions.assertEquals(false, b.value())
|
||||||
Assertions.assertEquals("ConstraintTest: Set true\nConstraintTest: Set false", b.getReasons(aapsLogger))
|
Assertions.assertEquals("ConstraintTest: Set true\nConstraintTest: Set false", b.getReasons())
|
||||||
Assertions.assertEquals("ConstraintTest: Set true\nConstraintTest: Set false", b.getMostLimitedReasons(aapsLogger))
|
Assertions.assertEquals("ConstraintTest: Set true\nConstraintTest: Set false", b.getMostLimitedReasons())
|
||||||
val d = Constraint(10.0)
|
val d = ConstraintObject(10.0, injector)
|
||||||
d.set(aapsLogger, 5.0, "Set 5d", this)
|
d.set(5.0, "Set 5d", this)
|
||||||
Assertions.assertEquals(5.0, d.value(), 0.01)
|
Assertions.assertEquals(5.0, d.value(), 0.01)
|
||||||
Assertions.assertEquals("ConstraintTest: Set 5d", d.getReasons(aapsLogger))
|
Assertions.assertEquals("ConstraintTest: Set 5d", d.getReasons())
|
||||||
Assertions.assertEquals("ConstraintTest: Set 5d", d.getMostLimitedReasons(aapsLogger))
|
Assertions.assertEquals("ConstraintTest: Set 5d", d.getMostLimitedReasons())
|
||||||
d.setIfSmaller(aapsLogger, 6.0, "Set 6d", this)
|
d.setIfSmaller(6.0, "Set 6d", this)
|
||||||
Assertions.assertEquals(5.0, d.value(), 0.01)
|
Assertions.assertEquals(5.0, d.value(), 0.01)
|
||||||
Assertions.assertEquals("ConstraintTest: Set 5d\nConstraintTest: Set 6d", d.getReasons(aapsLogger))
|
Assertions.assertEquals("ConstraintTest: Set 5d\nConstraintTest: Set 6d", d.getReasons())
|
||||||
Assertions.assertEquals("ConstraintTest: Set 5d", d.getMostLimitedReasons(aapsLogger))
|
Assertions.assertEquals("ConstraintTest: Set 5d", d.getMostLimitedReasons())
|
||||||
d.setIfSmaller(aapsLogger, 4.0, "Set 4d", this)
|
d.setIfSmaller(4.0, "Set 4d", this)
|
||||||
Assertions.assertEquals(4.0, d.value(), 0.01)
|
Assertions.assertEquals(4.0, d.value(), 0.01)
|
||||||
Assertions.assertEquals("ConstraintTest: Set 5d\nConstraintTest: Set 6d\nConstraintTest: Set 4d", d.getReasons(aapsLogger))
|
Assertions.assertEquals("ConstraintTest: Set 5d\nConstraintTest: Set 6d\nConstraintTest: Set 4d", d.getReasons())
|
||||||
Assertions.assertEquals("ConstraintTest: Set 4d", d.getMostLimitedReasons(aapsLogger))
|
Assertions.assertEquals("ConstraintTest: Set 4d", d.getMostLimitedReasons())
|
||||||
Assertions.assertEquals(10.0, d.originalValue(), 0.01)
|
Assertions.assertEquals(10.0, d.originalValue(), 0.01)
|
||||||
d.setIfDifferent(aapsLogger, 7.0, "Set 7d", this)
|
d.setIfDifferent(7.0, "Set 7d", this)
|
||||||
Assertions.assertEquals(7.0, d.value(), 0.01)
|
Assertions.assertEquals(7.0, d.value(), 0.01)
|
||||||
Assertions.assertEquals("ConstraintTest: Set 5d\nConstraintTest: Set 6d\nConstraintTest: Set 4d\nConstraintTest: Set 7d", d.getReasons(aapsLogger))
|
Assertions.assertEquals("ConstraintTest: Set 5d\nConstraintTest: Set 6d\nConstraintTest: Set 4d\nConstraintTest: Set 7d", d.getReasons())
|
||||||
Assertions.assertEquals("ConstraintTest: Set 4d\nConstraintTest: Set 7d", d.getMostLimitedReasons(aapsLogger))
|
Assertions.assertEquals("ConstraintTest: Set 4d\nConstraintTest: Set 7d", d.getMostLimitedReasons())
|
||||||
Assertions.assertEquals(10.0, d.originalValue(), 0.01)
|
Assertions.assertEquals(10.0, d.originalValue(), 0.01)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import info.nightscout.core.iob.plus
|
||||||
import info.nightscout.core.iob.round
|
import info.nightscout.core.iob.round
|
||||||
import info.nightscout.interfaces.iob.IobTotal
|
import info.nightscout.interfaces.iob.IobTotal
|
||||||
import info.nightscout.shared.utils.DateUtil
|
import info.nightscout.shared.utils.DateUtil
|
||||||
|
import info.nightscout.shared.utils.DateUtilImpl
|
||||||
import info.nightscout.sharedtests.TestBase
|
import info.nightscout.sharedtests.TestBase
|
||||||
import org.junit.jupiter.api.Assertions
|
import org.junit.jupiter.api.Assertions
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
|
@ -25,7 +26,7 @@ class IobTotalTest : TestBase() {
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
fun prepare() {
|
fun prepare() {
|
||||||
dateUtil = DateUtil(context)
|
dateUtil = DateUtilImpl(context)
|
||||||
now = dateUtil.now()
|
now = dateUtil.now()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,11 +7,10 @@ import info.nightscout.core.profile.ProfileSealed
|
||||||
import info.nightscout.interfaces.Config
|
import info.nightscout.interfaces.Config
|
||||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||||
import info.nightscout.interfaces.utils.HardLimits
|
import info.nightscout.interfaces.utils.HardLimits
|
||||||
import info.nightscout.rx.TestAapsSchedulers
|
|
||||||
import info.nightscout.rx.bus.RxBus
|
|
||||||
import info.nightscout.shared.interfaces.ResourceHelper
|
import info.nightscout.shared.interfaces.ResourceHelper
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
import info.nightscout.shared.utils.DateUtil
|
import info.nightscout.shared.utils.DateUtil
|
||||||
|
import info.nightscout.shared.utils.DateUtilImpl
|
||||||
import info.nightscout.sharedtests.HardLimitsMock
|
import info.nightscout.sharedtests.HardLimitsMock
|
||||||
import info.nightscout.sharedtests.TestBase
|
import info.nightscout.sharedtests.TestBase
|
||||||
import info.nightscout.sharedtests.TestPumpPlugin
|
import info.nightscout.sharedtests.TestPumpPlugin
|
||||||
|
@ -37,7 +36,6 @@ class ProfileTest : TestBase() {
|
||||||
@Mock lateinit var sp: SP
|
@Mock lateinit var sp: SP
|
||||||
|
|
||||||
private lateinit var hardLimits: HardLimits
|
private lateinit var hardLimits: HardLimits
|
||||||
private lateinit var rxBus: RxBus
|
|
||||||
private lateinit var dateUtil: DateUtil
|
private lateinit var dateUtil: DateUtil
|
||||||
private lateinit var testPumpPlugin: TestPumpPlugin
|
private lateinit var testPumpPlugin: TestPumpPlugin
|
||||||
|
|
||||||
|
@ -59,8 +57,7 @@ class ProfileTest : TestBase() {
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
fun prepare() {
|
fun prepare() {
|
||||||
testPumpPlugin = TestPumpPlugin { AndroidInjector { } }
|
testPumpPlugin = TestPumpPlugin { AndroidInjector { } }
|
||||||
dateUtil = DateUtil(context)
|
dateUtil = DateUtilImpl(context)
|
||||||
rxBus = RxBus(TestAapsSchedulers(), aapsLogger)
|
|
||||||
hardLimits = HardLimitsMock(sp, rh)
|
hardLimits = HardLimitsMock(sp, rh)
|
||||||
`when`(activePluginProvider.activePump).thenReturn(testPumpPlugin)
|
`when`(activePluginProvider.activePump).thenReturn(testPumpPlugin)
|
||||||
`when`(rh.gs(info.nightscout.core.ui.R.string.profile_per_unit)).thenReturn("/U")
|
`when`(rh.gs(info.nightscout.core.ui.R.string.profile_per_unit)).thenReturn("/U")
|
||||||
|
|
|
@ -3,13 +3,13 @@ package info.nightscout.core.utils
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import info.nightscout.shared.interfaces.ResourceHelper
|
import info.nightscout.shared.interfaces.ResourceHelper
|
||||||
import info.nightscout.shared.utils.DateUtil
|
import info.nightscout.shared.utils.DateUtilImpl
|
||||||
import info.nightscout.shared.utils.T
|
import info.nightscout.shared.utils.T
|
||||||
import info.nightscout.sharedtests.TestBase
|
import info.nightscout.sharedtests.TestBase
|
||||||
import org.junit.jupiter.api.Assertions
|
|
||||||
import org.junit.jupiter.api.Test
|
|
||||||
import org.junit.jupiter.api.BeforeAll
|
|
||||||
import org.junit.jupiter.api.AfterAll
|
import org.junit.jupiter.api.AfterAll
|
||||||
|
import org.junit.jupiter.api.Assertions
|
||||||
|
import org.junit.jupiter.api.BeforeAll
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
import org.mockito.Mockito.`when`
|
import org.mockito.Mockito.`when`
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
@ -41,45 +41,45 @@ class DateUtilTest : TestBase() {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun fromISODateStringTest() {
|
fun fromISODateStringTest() {
|
||||||
Assertions.assertEquals(1511124634417L, DateUtil(context).fromISODateString("2017-11-19T22:50:34.417+0200"))
|
Assertions.assertEquals(1511124634417L, DateUtilImpl(context).fromISODateString("2017-11-19T22:50:34.417+0200"))
|
||||||
Assertions.assertEquals(1511124634000L, DateUtil(context).fromISODateString("2017-11-19T22:50:34+0200"))
|
Assertions.assertEquals(1511124634000L, DateUtilImpl(context).fromISODateString("2017-11-19T22:50:34+0200"))
|
||||||
Assertions.assertEquals(1512317365000L, DateUtil(context).fromISODateString("2017-12-03T16:09:25.000Z"))
|
Assertions.assertEquals(1512317365000L, DateUtilImpl(context).fromISODateString("2017-12-03T16:09:25.000Z"))
|
||||||
Assertions.assertEquals(1513902750000L, DateUtil(context).fromISODateString("2017-12-22T00:32:30Z"))
|
Assertions.assertEquals(1513902750000L, DateUtilImpl(context).fromISODateString("2017-12-22T00:32:30Z"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun toISOStringTest() {
|
fun toISOStringTest() {
|
||||||
Assertions.assertEquals("2017-12-22T00:32:30.000Z", DateUtil(context).toISOString(1513902750000L))
|
Assertions.assertEquals("2017-12-22T00:32:30.000Z", DateUtilImpl(context).toISOString(1513902750000L))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun secondsOfTheDayToMillisecondsTest() {
|
@Test fun secondsOfTheDayToMillisecondsTest() {
|
||||||
Assertions.assertTrue(Date(DateUtil(context).secondsOfTheDayToMilliseconds((T.hours(1).secs() + T.mins(1).secs() + 1).toInt())).toString().contains("01:01:00"))
|
Assertions.assertTrue(Date(DateUtilImpl(context).secondsOfTheDayToMilliseconds((T.hours(1).secs() + T.mins(1).secs() + 1).toInt())).toString().contains("01:01:00"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun toSecondsTest() {
|
@Test fun toSecondsTest() {
|
||||||
Assertions.assertEquals(3600, DateUtil(context).toSeconds("01:00").toLong())
|
Assertions.assertEquals(3600, DateUtilImpl(context).toSeconds("01:00").toLong())
|
||||||
Assertions.assertEquals(3600, DateUtil(context).toSeconds("01:00 a.m.").toLong())
|
Assertions.assertEquals(3600, DateUtilImpl(context).toSeconds("01:00 a.m.").toLong())
|
||||||
Assertions.assertEquals(3600, DateUtil(context).toSeconds("01:00 AM").toLong())
|
Assertions.assertEquals(3600, DateUtilImpl(context).toSeconds("01:00 AM").toLong())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun dateStringTest() {
|
@Test fun dateStringTest() {
|
||||||
assertThat(DateUtil(context).dateString(1513902750000L)).contains("22")
|
assertThat(DateUtilImpl(context).dateString(1513902750000L)).contains("22")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun timeStringTest() {
|
@Test fun timeStringTest() {
|
||||||
Assertions.assertTrue(DateUtil(context).timeString(1513902750000L).contains("32"))
|
Assertions.assertTrue(DateUtilImpl(context).timeString(1513902750000L).contains("32"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun dateAndTimeStringTest() {
|
@Test fun dateAndTimeStringTest() {
|
||||||
assertThat(DateUtil(context).dateAndTimeString(1513902750000L)).contains("22")
|
assertThat(DateUtilImpl(context).dateAndTimeString(1513902750000L)).contains("22")
|
||||||
assertThat(DateUtil(context).dateAndTimeString(1513902750000L)).contains("32")
|
assertThat(DateUtilImpl(context).dateAndTimeString(1513902750000L)).contains("32")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun dateAndTimeRangeStringTest() {
|
@Test fun dateAndTimeRangeStringTest() {
|
||||||
assertThat(DateUtil(context).dateAndTimeRangeString(1513902750000L, 1513902750000L)).contains("22")
|
assertThat(DateUtilImpl(context).dateAndTimeRangeString(1513902750000L, 1513902750000L)).contains("22")
|
||||||
assertThat(DateUtil(context).dateAndTimeRangeString(1513902750000L, 1513902750000L)).contains("32")
|
assertThat(DateUtilImpl(context).dateAndTimeRangeString(1513902750000L, 1513902750000L)).contains("32")
|
||||||
assertThat(DateUtil(context).dateAndTimeRangeString(1513902750000L, 1513902750000L)).contains("22")
|
assertThat(DateUtilImpl(context).dateAndTimeRangeString(1513902750000L, 1513902750000L)).contains("22")
|
||||||
assertThat(DateUtil(context).dateAndTimeRangeString(1513902750000L, 1513902750000L)).contains("32")
|
assertThat(DateUtilImpl(context).dateAndTimeRangeString(1513902750000L, 1513902750000L)).contains("32")
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -90,6 +90,6 @@ class DateUtilTest : TestBase() {
|
||||||
*/
|
*/
|
||||||
@Test fun timeFrameStringTest() {
|
@Test fun timeFrameStringTest() {
|
||||||
`when`(rh.gs(info.nightscout.interfaces.R.string.shorthour)).thenReturn("h")
|
`when`(rh.gs(info.nightscout.interfaces.R.string.shorthour)).thenReturn("h")
|
||||||
Assertions.assertEquals("(1h 1')", DateUtil(context).timeFrameString(T.hours(1).msecs() + T.mins(1).msecs(), rh))
|
Assertions.assertEquals("(1h 1')", DateUtilImpl(context).timeFrameString(T.hours(1).msecs() + T.mins(1).msecs(), rh))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ dependencies {
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||||
androidTestImplementation "androidx.test.ext:junit-ktx:$androidx_junit_version"
|
androidTestImplementation "androidx.test.ext:junit-ktx:$androidx_junit_version"
|
||||||
androidTestImplementation "androidx.test:rules:$androidx_rules_version"
|
androidTestImplementation "androidx.test:rules:$androidx_rules_version"
|
||||||
|
androidTestImplementation "org.junit.jupiter:junit-jupiter-api:$junit_jupiter_version"
|
||||||
|
|
||||||
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
|
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import android.text.Spanned
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.annotations.OpenForTesting
|
import info.nightscout.annotations.OpenForTesting
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.core.events.EventNewNotification
|
import info.nightscout.core.events.EventNewNotification
|
||||||
import info.nightscout.core.extensions.getCustomizedName
|
import info.nightscout.core.extensions.getCustomizedName
|
||||||
import info.nightscout.core.profile.ProfileSealed
|
import info.nightscout.core.profile.ProfileSealed
|
||||||
|
@ -42,8 +43,7 @@ import info.nightscout.implementation.queue.commands.CommandTempBasalPercent
|
||||||
import info.nightscout.implementation.queue.commands.CommandUpdateTime
|
import info.nightscout.implementation.queue.commands.CommandUpdateTime
|
||||||
import info.nightscout.interfaces.AndroidPermission
|
import info.nightscout.interfaces.AndroidPermission
|
||||||
import info.nightscout.interfaces.Config
|
import info.nightscout.interfaces.Config
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
|
||||||
import info.nightscout.interfaces.db.PersistenceLayer
|
import info.nightscout.interfaces.db.PersistenceLayer
|
||||||
import info.nightscout.interfaces.notifications.Notification
|
import info.nightscout.interfaces.notifications.Notification
|
||||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||||
|
@ -85,7 +85,7 @@ class CommandQueueImplementation @Inject constructor(
|
||||||
private val rxBus: RxBus,
|
private val rxBus: RxBus,
|
||||||
private val aapsSchedulers: AapsSchedulers,
|
private val aapsSchedulers: AapsSchedulers,
|
||||||
private val rh: ResourceHelper,
|
private val rh: ResourceHelper,
|
||||||
private val constraintChecker: Constraints,
|
private val constraintChecker: ConstraintsChecker,
|
||||||
private val profileFunction: ProfileFunction,
|
private val profileFunction: ProfileFunction,
|
||||||
private val activePlugin: ActivePlugin,
|
private val activePlugin: ActivePlugin,
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
|
@ -310,8 +310,8 @@ class CommandQueueImplementation @Inject constructor(
|
||||||
removeAll(type)
|
removeAll(type)
|
||||||
}
|
}
|
||||||
// apply constraints
|
// apply constraints
|
||||||
detailedBolusInfo.insulin = constraintChecker.applyBolusConstraints(Constraint(detailedBolusInfo.insulin)).value()
|
detailedBolusInfo.insulin = constraintChecker.applyBolusConstraints(ConstraintObject(detailedBolusInfo.insulin, injector)).value()
|
||||||
detailedBolusInfo.carbs = constraintChecker.applyCarbsConstraints(Constraint(detailedBolusInfo.carbs.toInt())).value().toDouble()
|
detailedBolusInfo.carbs = constraintChecker.applyCarbsConstraints(ConstraintObject(detailedBolusInfo.carbs.toInt(), injector)).value().toDouble()
|
||||||
// add new command to queue
|
// add new command to queue
|
||||||
if (detailedBolusInfo.bolusType == DetailedBolusInfo.BolusType.SMB) {
|
if (detailedBolusInfo.bolusType == DetailedBolusInfo.BolusType.SMB) {
|
||||||
add(CommandSMBBolus(injector, detailedBolusInfo, callback))
|
add(CommandSMBBolus(injector, detailedBolusInfo, callback))
|
||||||
|
@ -368,7 +368,7 @@ class CommandQueueImplementation @Inject constructor(
|
||||||
}
|
}
|
||||||
// remove all unfinished
|
// remove all unfinished
|
||||||
removeAll(CommandType.TEMPBASAL)
|
removeAll(CommandType.TEMPBASAL)
|
||||||
val rateAfterConstraints = constraintChecker.applyBasalConstraints(Constraint(absoluteRate), profile).value()
|
val rateAfterConstraints = constraintChecker.applyBasalConstraints(ConstraintObject(absoluteRate, injector), profile).value()
|
||||||
// add new command to queue
|
// add new command to queue
|
||||||
add(CommandTempBasalAbsolute(injector, rateAfterConstraints, durationInMinutes, enforceNew, profile, tbrType, callback))
|
add(CommandTempBasalAbsolute(injector, rateAfterConstraints, durationInMinutes, enforceNew, profile, tbrType, callback))
|
||||||
notifyAboutNewCommand()
|
notifyAboutNewCommand()
|
||||||
|
@ -383,7 +383,7 @@ class CommandQueueImplementation @Inject constructor(
|
||||||
}
|
}
|
||||||
// remove all unfinished
|
// remove all unfinished
|
||||||
removeAll(CommandType.TEMPBASAL)
|
removeAll(CommandType.TEMPBASAL)
|
||||||
val percentAfterConstraints = constraintChecker.applyBasalPercentConstraints(Constraint(percent), profile).value()
|
val percentAfterConstraints = constraintChecker.applyBasalPercentConstraints(ConstraintObject(percent, injector), profile).value()
|
||||||
// add new command to queue
|
// add new command to queue
|
||||||
add(CommandTempBasalPercent(injector, percentAfterConstraints, durationInMinutes, enforceNew, profile, tbrType, callback))
|
add(CommandTempBasalPercent(injector, percentAfterConstraints, durationInMinutes, enforceNew, profile, tbrType, callback))
|
||||||
notifyAboutNewCommand()
|
notifyAboutNewCommand()
|
||||||
|
@ -396,7 +396,7 @@ class CommandQueueImplementation @Inject constructor(
|
||||||
callback?.result(executingNowError())?.run()
|
callback?.result(executingNowError())?.run()
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
val rateAfterConstraints = constraintChecker.applyExtendedBolusConstraints(Constraint(insulin)).value()
|
val rateAfterConstraints = constraintChecker.applyExtendedBolusConstraints(ConstraintObject(insulin, injector)).value()
|
||||||
// remove all unfinished
|
// remove all unfinished
|
||||||
removeAll(CommandType.EXTENDEDBOLUS)
|
removeAll(CommandType.EXTENDEDBOLUS)
|
||||||
// add new command to queue
|
// add new command to queue
|
||||||
|
|
|
@ -5,6 +5,7 @@ import android.os.Handler
|
||||||
import android.os.PowerManager
|
import android.os.PowerManager
|
||||||
import dagger.android.AndroidInjector
|
import dagger.android.AndroidInjector
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||||
import info.nightscout.database.ValueWrapper
|
import info.nightscout.database.ValueWrapper
|
||||||
import info.nightscout.database.entities.Bolus
|
import info.nightscout.database.entities.Bolus
|
||||||
|
@ -16,8 +17,7 @@ import info.nightscout.implementation.queue.commands.CommandLoadHistory
|
||||||
import info.nightscout.implementation.queue.commands.CommandTempBasalPercent
|
import info.nightscout.implementation.queue.commands.CommandTempBasalPercent
|
||||||
import info.nightscout.interfaces.AndroidPermission
|
import info.nightscout.interfaces.AndroidPermission
|
||||||
import info.nightscout.interfaces.Config
|
import info.nightscout.interfaces.Config
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
|
||||||
import info.nightscout.interfaces.db.PersistenceLayer
|
import info.nightscout.interfaces.db.PersistenceLayer
|
||||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||||
import info.nightscout.interfaces.profile.ProfileFunction
|
import info.nightscout.interfaces.profile.ProfileFunction
|
||||||
|
@ -50,7 +50,7 @@ import java.util.Calendar
|
||||||
|
|
||||||
class CommandQueueImplementationTest : TestBaseWithProfile() {
|
class CommandQueueImplementationTest : TestBaseWithProfile() {
|
||||||
|
|
||||||
@Mock lateinit var constraintChecker: Constraints
|
@Mock lateinit var constraintChecker: ConstraintsChecker
|
||||||
@Mock lateinit var powerManager: PowerManager
|
@Mock lateinit var powerManager: PowerManager
|
||||||
@Mock lateinit var repository: AppRepository
|
@Mock lateinit var repository: AppRepository
|
||||||
@Mock lateinit var uiInteraction: UiInteraction
|
@Mock lateinit var uiInteraction: UiInteraction
|
||||||
|
@ -63,7 +63,7 @@ class CommandQueueImplementationTest : TestBaseWithProfile() {
|
||||||
rxBus: RxBus,
|
rxBus: RxBus,
|
||||||
aapsSchedulers: AapsSchedulers,
|
aapsSchedulers: AapsSchedulers,
|
||||||
rh: ResourceHelper,
|
rh: ResourceHelper,
|
||||||
constraintChecker: Constraints,
|
constraintChecker: ConstraintsChecker,
|
||||||
profileFunction: ProfileFunction,
|
profileFunction: ProfileFunction,
|
||||||
activePlugin: ActivePlugin,
|
activePlugin: ActivePlugin,
|
||||||
context: Context,
|
context: Context,
|
||||||
|
@ -88,6 +88,9 @@ class CommandQueueImplementationTest : TestBaseWithProfile() {
|
||||||
|
|
||||||
private val injector = HasAndroidInjector {
|
private val injector = HasAndroidInjector {
|
||||||
AndroidInjector {
|
AndroidInjector {
|
||||||
|
if (it is ConstraintObject<*>) {
|
||||||
|
it.aapsLogger = aapsLogger
|
||||||
|
}
|
||||||
if (it is Command) {
|
if (it is Command) {
|
||||||
it.aapsLogger = aapsLogger
|
it.aapsLogger = aapsLogger
|
||||||
it.rh = rh
|
it.rh = rh
|
||||||
|
@ -140,14 +143,14 @@ class CommandQueueImplementationTest : TestBaseWithProfile() {
|
||||||
)
|
)
|
||||||
`when`(profileFunction.getProfile()).thenReturn(validProfile)
|
`when`(profileFunction.getProfile()).thenReturn(validProfile)
|
||||||
|
|
||||||
val bolusConstraint = Constraint(0.0)
|
val bolusConstraint = ConstraintObject(0.0, injector)
|
||||||
`when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(bolusConstraint)
|
`when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(bolusConstraint)
|
||||||
`when`(constraintChecker.applyExtendedBolusConstraints(anyObject())).thenReturn(bolusConstraint)
|
`when`(constraintChecker.applyExtendedBolusConstraints(anyObject())).thenReturn(bolusConstraint)
|
||||||
val carbsConstraint = Constraint(0)
|
val carbsConstraint = ConstraintObject(0, injector)
|
||||||
`when`(constraintChecker.applyCarbsConstraints(anyObject())).thenReturn(carbsConstraint)
|
`when`(constraintChecker.applyCarbsConstraints(anyObject())).thenReturn(carbsConstraint)
|
||||||
val rateConstraint = Constraint(0.0)
|
val rateConstraint = ConstraintObject(0.0, injector)
|
||||||
`when`(constraintChecker.applyBasalConstraints(anyObject(), anyObject())).thenReturn(rateConstraint)
|
`when`(constraintChecker.applyBasalConstraints(anyObject(), anyObject())).thenReturn(rateConstraint)
|
||||||
val percentageConstraint = Constraint(0)
|
val percentageConstraint = ConstraintObject(0, injector)
|
||||||
`when`(constraintChecker.applyBasalPercentConstraints(anyObject(), anyObject())).thenReturn(percentageConstraint)
|
`when`(constraintChecker.applyBasalPercentConstraints(anyObject(), anyObject())).thenReturn(percentageConstraint)
|
||||||
`when`(rh.gs(info.nightscout.core.ui.R.string.connectiontimedout)).thenReturn("Connection timed out")
|
`when`(rh.gs(info.nightscout.core.ui.R.string.connectiontimedout)).thenReturn("Connection timed out")
|
||||||
`when`(rh.gs(info.nightscout.core.ui.R.string.format_insulin_units)).thenReturn("%1\$.2f U")
|
`when`(rh.gs(info.nightscout.core.ui.R.string.format_insulin_units)).thenReturn("%1\$.2f U")
|
||||||
|
|
|
@ -4,11 +4,11 @@ import android.content.Context
|
||||||
import android.os.PowerManager
|
import android.os.PowerManager
|
||||||
import dagger.android.AndroidInjector
|
import dagger.android.AndroidInjector
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.database.impl.AppRepository
|
import info.nightscout.database.impl.AppRepository
|
||||||
import info.nightscout.implementation.queue.commands.CommandTempBasalAbsolute
|
import info.nightscout.implementation.queue.commands.CommandTempBasalAbsolute
|
||||||
import info.nightscout.interfaces.AndroidPermission
|
import info.nightscout.interfaces.AndroidPermission
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
|
||||||
import info.nightscout.interfaces.db.PersistenceLayer
|
import info.nightscout.interfaces.db.PersistenceLayer
|
||||||
import info.nightscout.interfaces.pump.PumpSync
|
import info.nightscout.interfaces.pump.PumpSync
|
||||||
import info.nightscout.interfaces.pump.defs.PumpDescription
|
import info.nightscout.interfaces.pump.defs.PumpDescription
|
||||||
|
@ -25,7 +25,7 @@ import org.mockito.Mockito
|
||||||
|
|
||||||
class QueueThreadTest : TestBaseWithProfile() {
|
class QueueThreadTest : TestBaseWithProfile() {
|
||||||
|
|
||||||
@Mock lateinit var constraintChecker: Constraints
|
@Mock lateinit var constraintChecker: ConstraintsChecker
|
||||||
@Mock lateinit var powerManager: PowerManager
|
@Mock lateinit var powerManager: PowerManager
|
||||||
@Mock lateinit var repository: AppRepository
|
@Mock lateinit var repository: AppRepository
|
||||||
@Mock lateinit var androidPermission: AndroidPermission
|
@Mock lateinit var androidPermission: AndroidPermission
|
||||||
|
@ -34,6 +34,9 @@ class QueueThreadTest : TestBaseWithProfile() {
|
||||||
|
|
||||||
private val injector = HasAndroidInjector {
|
private val injector = HasAndroidInjector {
|
||||||
AndroidInjector {
|
AndroidInjector {
|
||||||
|
if (it is ConstraintObject<*>) {
|
||||||
|
it.aapsLogger = aapsLogger
|
||||||
|
}
|
||||||
if (it is Command) {
|
if (it is Command) {
|
||||||
it.aapsLogger = aapsLogger
|
it.aapsLogger = aapsLogger
|
||||||
it.rh = rh
|
it.rh = rh
|
||||||
|
@ -64,14 +67,14 @@ class QueueThreadTest : TestBaseWithProfile() {
|
||||||
Mockito.`when`(context.getSystemService(Context.POWER_SERVICE)).thenReturn(powerManager)
|
Mockito.`when`(context.getSystemService(Context.POWER_SERVICE)).thenReturn(powerManager)
|
||||||
Mockito.`when`(profileFunction.getProfile()).thenReturn(validProfile)
|
Mockito.`when`(profileFunction.getProfile()).thenReturn(validProfile)
|
||||||
|
|
||||||
val bolusConstraint = Constraint(0.0)
|
val bolusConstraint = ConstraintObject(0.0, injector)
|
||||||
Mockito.`when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(bolusConstraint)
|
Mockito.`when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(bolusConstraint)
|
||||||
Mockito.`when`(constraintChecker.applyExtendedBolusConstraints(anyObject())).thenReturn(bolusConstraint)
|
Mockito.`when`(constraintChecker.applyExtendedBolusConstraints(anyObject())).thenReturn(bolusConstraint)
|
||||||
val carbsConstraint = Constraint(0)
|
val carbsConstraint = ConstraintObject(0, injector)
|
||||||
Mockito.`when`(constraintChecker.applyCarbsConstraints(anyObject())).thenReturn(carbsConstraint)
|
Mockito.`when`(constraintChecker.applyCarbsConstraints(anyObject())).thenReturn(carbsConstraint)
|
||||||
val rateConstraint = Constraint(0.0)
|
val rateConstraint = ConstraintObject(0.0, injector)
|
||||||
Mockito.`when`(constraintChecker.applyBasalConstraints(anyObject(), anyObject())).thenReturn(rateConstraint)
|
Mockito.`when`(constraintChecker.applyBasalConstraints(anyObject(), anyObject())).thenReturn(rateConstraint)
|
||||||
val percentageConstraint = Constraint(0)
|
val percentageConstraint = ConstraintObject(0, injector)
|
||||||
Mockito.`when`(constraintChecker.applyBasalPercentConstraints(anyObject(), anyObject()))
|
Mockito.`when`(constraintChecker.applyBasalPercentConstraints(anyObject(), anyObject()))
|
||||||
.thenReturn(percentageConstraint)
|
.thenReturn(percentageConstraint)
|
||||||
Mockito.`when`(rh.gs(ArgumentMatchers.eq(info.nightscout.core.ui.R.string.temp_basal_absolute), anyObject(), anyObject())).thenReturn("TEMP BASAL %1\$.2f U/h %2\$d min")
|
Mockito.`when`(rh.gs(ArgumentMatchers.eq(info.nightscout.core.ui.R.string.temp_basal_absolute), anyObject(), anyObject())).thenReturn("TEMP BASAL %1\$.2f U/h %2\$d min")
|
||||||
|
|
|
@ -8,12 +8,11 @@ import info.nightscout.implementation.iob.GlucoseStatusProviderImpl
|
||||||
import info.nightscout.interfaces.aps.AutosensDataStore
|
import info.nightscout.interfaces.aps.AutosensDataStore
|
||||||
import info.nightscout.interfaces.aps.Loop
|
import info.nightscout.interfaces.aps.Loop
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.Constraint
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.iob.IobTotal
|
import info.nightscout.interfaces.iob.IobTotal
|
||||||
import info.nightscout.interfaces.profile.Profile
|
import info.nightscout.interfaces.profile.Profile
|
||||||
import info.nightscout.interfaces.pump.defs.PumpDescription
|
import info.nightscout.interfaces.pump.defs.PumpDescription
|
||||||
import info.nightscout.interfaces.queue.CommandQueue
|
import info.nightscout.interfaces.queue.CommandQueue
|
||||||
import info.nightscout.rx.bus.RxBus
|
|
||||||
import info.nightscout.sharedtests.TestBaseWithProfile
|
import info.nightscout.sharedtests.TestBaseWithProfile
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
|
@ -24,7 +23,7 @@ class BolusWizardTest : TestBaseWithProfile() {
|
||||||
|
|
||||||
private val pumpBolusStep = 0.1
|
private val pumpBolusStep = 0.1
|
||||||
|
|
||||||
@Mock lateinit var constraintChecker: Constraints
|
@Mock lateinit var constraintChecker: ConstraintsChecker
|
||||||
@Mock lateinit var commandQueue: CommandQueue
|
@Mock lateinit var commandQueue: CommandQueue
|
||||||
@Mock lateinit var loop: Loop
|
@Mock lateinit var loop: Loop
|
||||||
@Mock lateinit var autosensDataStore: AutosensDataStore
|
@Mock lateinit var autosensDataStore: AutosensDataStore
|
||||||
|
@ -34,7 +33,7 @@ class BolusWizardTest : TestBaseWithProfile() {
|
||||||
if (it is BolusWizard) {
|
if (it is BolusWizard) {
|
||||||
it.aapsLogger = aapsLogger
|
it.aapsLogger = aapsLogger
|
||||||
it.rh = rh
|
it.rh = rh
|
||||||
it.rxBus = RxBus(aapsSchedulers, aapsLogger)
|
it.rxBus = rxBus
|
||||||
it.profileFunction = profileFunction
|
it.profileFunction = profileFunction
|
||||||
it.constraintChecker = constraintChecker
|
it.constraintChecker = constraintChecker
|
||||||
it.activePlugin = activePlugin
|
it.activePlugin = activePlugin
|
||||||
|
|
|
@ -103,7 +103,7 @@ import info.nightscout.androidaps.plugins.pump.insight.utils.ParameterBlockUtil;
|
||||||
import info.nightscout.core.events.EventNewNotification;
|
import info.nightscout.core.events.EventNewNotification;
|
||||||
import info.nightscout.interfaces.Config;
|
import info.nightscout.interfaces.Config;
|
||||||
import info.nightscout.interfaces.constraints.Constraint;
|
import info.nightscout.interfaces.constraints.Constraint;
|
||||||
import info.nightscout.interfaces.constraints.Constraints;
|
import info.nightscout.interfaces.constraints.PluginConstraints;
|
||||||
import info.nightscout.interfaces.notifications.Notification;
|
import info.nightscout.interfaces.notifications.Notification;
|
||||||
import info.nightscout.interfaces.plugin.OwnDatabasePlugin;
|
import info.nightscout.interfaces.plugin.OwnDatabasePlugin;
|
||||||
import info.nightscout.interfaces.plugin.PluginDescription;
|
import info.nightscout.interfaces.plugin.PluginDescription;
|
||||||
|
@ -134,9 +134,10 @@ import info.nightscout.shared.utils.DateUtil;
|
||||||
import info.nightscout.shared.utils.T;
|
import info.nightscout.shared.utils.T;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class LocalInsightPlugin extends PumpPluginBase implements Pump, Insight, Constraints, OwnDatabasePlugin,
|
public class LocalInsightPlugin extends PumpPluginBase implements Pump, Insight, PluginConstraints, OwnDatabasePlugin,
|
||||||
InsightConnectionService.StateCallback {
|
InsightConnectionService.StateCallback {
|
||||||
|
|
||||||
|
public static final String ALERT_CHANNEL_ID = "AAPS-InsightAlert";
|
||||||
private final AAPSLogger aapsLogger;
|
private final AAPSLogger aapsLogger;
|
||||||
private final RxBus rxBus;
|
private final RxBus rxBus;
|
||||||
private final ResourceHelper rh;
|
private final ResourceHelper rh;
|
||||||
|
@ -148,13 +149,12 @@ public class LocalInsightPlugin extends PumpPluginBase implements Pump, Insight,
|
||||||
private final InsightDbHelper insightDbHelper;
|
private final InsightDbHelper insightDbHelper;
|
||||||
private final PumpSync pumpSync;
|
private final PumpSync pumpSync;
|
||||||
private final InsightDatabase insightDatabase;
|
private final InsightDatabase insightDatabase;
|
||||||
|
|
||||||
public static final String ALERT_CHANNEL_ID = "AAPS-InsightAlert";
|
|
||||||
|
|
||||||
private final PumpDescription pumpDescription;
|
private final PumpDescription pumpDescription;
|
||||||
|
private final Object $bolusLock = new Object[0];
|
||||||
|
public double lastBolusAmount = 0;
|
||||||
|
public long lastBolusTimestamp = 0L;
|
||||||
private InsightAlertService alertService;
|
private InsightAlertService alertService;
|
||||||
private InsightConnectionService connectionService;
|
private InsightConnectionService connectionService;
|
||||||
private long timeOffset;
|
|
||||||
private final ServiceConnection serviceConnection = new ServiceConnection() {
|
private final ServiceConnection serviceConnection = new ServiceConnection() {
|
||||||
@Override
|
@Override
|
||||||
public void onServiceConnected(ComponentName name, IBinder binder) {
|
public void onServiceConnected(ComponentName name, IBinder binder) {
|
||||||
|
@ -174,8 +174,7 @@ public class LocalInsightPlugin extends PumpPluginBase implements Pump, Insight,
|
||||||
connectionService = null;
|
connectionService = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
private long timeOffset;
|
||||||
private final Object $bolusLock = new Object[0];
|
|
||||||
private int bolusID;
|
private int bolusID;
|
||||||
private boolean bolusCancelled;
|
private boolean bolusCancelled;
|
||||||
private BasalProfile activeBasalProfile;
|
private BasalProfile activeBasalProfile;
|
||||||
|
@ -192,8 +191,6 @@ public class LocalInsightPlugin extends PumpPluginBase implements Pump, Insight,
|
||||||
private List<ActiveBolus> activeBoluses;
|
private List<ActiveBolus> activeBoluses;
|
||||||
private boolean statusLoaded;
|
private boolean statusLoaded;
|
||||||
private TBROverNotificationBlock tbrOverNotificationBlock;
|
private TBROverNotificationBlock tbrOverNotificationBlock;
|
||||||
public double lastBolusAmount = 0;
|
|
||||||
public long lastBolusTimestamp = 0L;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public LocalInsightPlugin(
|
public LocalInsightPlugin(
|
||||||
|
@ -1589,22 +1586,22 @@ public class LocalInsightPlugin extends PumpPluginBase implements Pump, Insight,
|
||||||
|
|
||||||
@NonNull @Override
|
@NonNull @Override
|
||||||
public Constraint<Integer> applyBasalPercentConstraints(Constraint<Integer> percentRate, @NonNull Profile profile) {
|
public Constraint<Integer> applyBasalPercentConstraints(Constraint<Integer> percentRate, @NonNull Profile profile) {
|
||||||
percentRate.setIfGreater(getAapsLogger(), 0, rh.gs(info.nightscout.core.ui.R.string.limitingpercentrate, 0, rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), this);
|
percentRate.setIfGreater(0, rh.gs(info.nightscout.core.ui.R.string.limitingpercentrate, 0, rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), this);
|
||||||
percentRate.setIfSmaller(getAapsLogger(), getPumpDescription().getMaxTempPercent(), rh.gs(info.nightscout.core.ui.R.string.limitingpercentrate, getPumpDescription().getMaxTempPercent(), rh.gs(info.nightscout.core.ui.R.string.pumplimit)), this);
|
percentRate.setIfSmaller(getPumpDescription().getMaxTempPercent(), rh.gs(info.nightscout.core.ui.R.string.limitingpercentrate, getPumpDescription().getMaxTempPercent(), rh.gs(info.nightscout.core.ui.R.string.pumplimit)), this);
|
||||||
return percentRate;
|
return percentRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull @Override
|
@NonNull @Override
|
||||||
public Constraint<Double> applyBolusConstraints(@NonNull Constraint<Double> insulin) {
|
public Constraint<Double> applyBolusConstraints(@NonNull Constraint<Double> insulin) {
|
||||||
if (!limitsFetched) return insulin;
|
if (!limitsFetched) return insulin;
|
||||||
insulin.setIfSmaller(getAapsLogger(), maximumBolusAmount, rh.gs(info.nightscout.core.ui.R.string.limitingbolus, maximumBolusAmount, rh.gs(info.nightscout.core.ui.R.string.pumplimit)), this);
|
insulin.setIfSmaller(maximumBolusAmount, rh.gs(info.nightscout.core.ui.R.string.limitingbolus, maximumBolusAmount, rh.gs(info.nightscout.core.ui.R.string.pumplimit)), this);
|
||||||
if (insulin.value() < minimumBolusAmount) {
|
if (insulin.value() < minimumBolusAmount) {
|
||||||
|
|
||||||
//TODO: Add function to Constraints or use different approach
|
//TODO: Add function to Constraints or use different approach
|
||||||
// This only works if the interface of the InsightPlugin is called last.
|
// This only works if the interface of the InsightPlugin is called last.
|
||||||
// If not, another constraint could theoretically set the value between 0 and minimumBolusAmount
|
// If not, another constraint could theoretically set the value between 0 and minimumBolusAmount
|
||||||
|
|
||||||
insulin.set(getAapsLogger(), 0d, rh.gs(info.nightscout.core.ui.R.string.limitingbolus, minimumBolusAmount, rh.gs(info.nightscout.core.ui.R.string.pumplimit)), this);
|
insulin.set(0d, rh.gs(info.nightscout.core.ui.R.string.limitingbolus, minimumBolusAmount, rh.gs(info.nightscout.core.ui.R.string.pumplimit)), this);
|
||||||
}
|
}
|
||||||
return insulin;
|
return insulin;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import info.nightscout.core.utils.HtmlHelper
|
||||||
import info.nightscout.database.entities.GlucoseValue
|
import info.nightscout.database.entities.GlucoseValue
|
||||||
import info.nightscout.interfaces.aps.APSResult
|
import info.nightscout.interfaces.aps.APSResult
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.Constraint
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.iob.IobCobCalculator
|
import info.nightscout.interfaces.iob.IobCobCalculator
|
||||||
import info.nightscout.interfaces.iob.IobTotal
|
import info.nightscout.interfaces.iob.IobTotal
|
||||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||||
|
@ -34,7 +34,7 @@ import kotlin.math.max
|
||||||
open class APSResultObject @Inject constructor(val injector: HasAndroidInjector) : APSResult {
|
open class APSResultObject @Inject constructor(val injector: HasAndroidInjector) : APSResult {
|
||||||
|
|
||||||
@Inject lateinit var aapsLogger: AAPSLogger
|
@Inject lateinit var aapsLogger: AAPSLogger
|
||||||
@Inject lateinit var constraintChecker: Constraints
|
@Inject lateinit var constraintChecker: ConstraintsChecker
|
||||||
@Inject lateinit var sp: SP
|
@Inject lateinit var sp: SP
|
||||||
@Inject lateinit var activePlugin: ActivePlugin
|
@Inject lateinit var activePlugin: ActivePlugin
|
||||||
@Inject lateinit var iobCobCalculator: IobCobCalculator
|
@Inject lateinit var iobCobCalculator: IobCobCalculator
|
||||||
|
@ -74,12 +74,12 @@ open class APSResultObject @Inject constructor(val injector: HasAndroidInjector)
|
||||||
val pump = activePlugin.activePump
|
val pump = activePlugin.activePump
|
||||||
if (isChangeRequested) {
|
if (isChangeRequested) {
|
||||||
// rate
|
// rate
|
||||||
var ret: String = if (rate == 0.0 && duration == 0) "${rh.gs(info.nightscout.core.ui.R.string.cancel_temp)} "
|
var ret: String = if (rate == 0.0 && duration == 0) "${rh.gs(R.string.cancel_temp)} "
|
||||||
else if (rate == -1.0) "${rh.gs(info.nightscout.core.ui.R.string.let_temp_basal_run)}\n"
|
else if (rate == -1.0) "${rh.gs(R.string.let_temp_basal_run)}\n"
|
||||||
else if (usePercent) "${rh.gs(info.nightscout.core.ui.R.string.rate)}: ${decimalFormatter.to2Decimal(percent.toDouble())}% (${decimalFormatter.to2Decimal(percent * pump.baseBasalRate / 100.0)} U/h) " +
|
else if (usePercent) "${rh.gs(R.string.rate)}: ${decimalFormatter.to2Decimal(percent.toDouble())}% (${decimalFormatter.to2Decimal(percent * pump.baseBasalRate / 100.0)} U/h) " +
|
||||||
"${rh.gs(info.nightscout.core.ui.R.string.duration)}: ${decimalFormatter.to2Decimal(duration.toDouble())} min "
|
"${rh.gs(R.string.duration)}: ${decimalFormatter.to2Decimal(duration.toDouble())} min "
|
||||||
else "${rh.gs(info.nightscout.core.ui.R.string.rate)}: ${decimalFormatter.to2Decimal(rate)} U/h (${decimalFormatter.to2Decimal(rate / pump.baseBasalRate * 100)}%) " +
|
else "${rh.gs(R.string.rate)}: ${decimalFormatter.to2Decimal(rate)} U/h (${decimalFormatter.to2Decimal(rate / pump.baseBasalRate * 100)}%) " +
|
||||||
"${rh.gs(info.nightscout.core.ui.R.string.duration)}: ${decimalFormatter.to2Decimal(duration.toDouble())} min "
|
"${rh.gs(R.string.duration)}: ${decimalFormatter.to2Decimal(duration.toDouble())} min "
|
||||||
// smb
|
// smb
|
||||||
if (smb != 0.0) ret += "SMB: ${decimalFormatter.toPumpSupportedBolus(smb, activePlugin.activePump.pumpDescription.bolusStep)} "
|
if (smb != 0.0) ret += "SMB: ${decimalFormatter.toPumpSupportedBolus(smb, activePlugin.activePump.pumpDescription.bolusStep)} "
|
||||||
if (isCarbsRequired) {
|
if (isCarbsRequired) {
|
||||||
|
@ -92,7 +92,7 @@ open class APSResultObject @Inject constructor(val injector: HasAndroidInjector)
|
||||||
}
|
}
|
||||||
return if (isCarbsRequired) {
|
return if (isCarbsRequired) {
|
||||||
carbsRequiredText
|
carbsRequiredText
|
||||||
} else rh.gs(info.nightscout.core.ui.R.string.nochangerequested)
|
} else rh.gs(R.string.nochangerequested)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toSpanned(): Spanned {
|
override fun toSpanned(): Spanned {
|
||||||
|
@ -100,17 +100,17 @@ open class APSResultObject @Inject constructor(val injector: HasAndroidInjector)
|
||||||
if (isChangeRequested) {
|
if (isChangeRequested) {
|
||||||
// rate
|
// rate
|
||||||
var ret: String =
|
var ret: String =
|
||||||
if (rate == 0.0 && duration == 0) rh.gs(info.nightscout.core.ui.R.string.cancel_temp) + "<br>" else if (rate == -1.0) rh.gs(info.nightscout.core.ui.R.string.let_temp_basal_run) + "<br>" else if (usePercent) "<b>" + rh.gs(
|
if (rate == 0.0 && duration == 0) rh.gs(R.string.cancel_temp) + "<br>" else if (rate == -1.0) rh.gs(R.string.let_temp_basal_run) + "<br>" else if (usePercent) "<b>" + rh.gs(
|
||||||
info.nightscout.core.ui.R.string.rate
|
R.string.rate
|
||||||
) + "</b>: " + decimalFormatter.to2Decimal(
|
) + "</b>: " + decimalFormatter.to2Decimal(
|
||||||
percent.toDouble()
|
percent.toDouble()
|
||||||
) + "% " +
|
) + "% " +
|
||||||
"(" + decimalFormatter.to2Decimal(percent * pump.baseBasalRate / 100.0) + " U/h)<br>" +
|
"(" + decimalFormatter.to2Decimal(percent * pump.baseBasalRate / 100.0) + " U/h)<br>" +
|
||||||
"<b>" + rh.gs(info.nightscout.core.ui.R.string.duration) + "</b>: " + decimalFormatter.to2Decimal(duration.toDouble()) + " min<br>" else "<b>" + rh.gs(info.nightscout.core.ui.R.string.rate) + "</b>: " + decimalFormatter.to2Decimal(
|
"<b>" + rh.gs(R.string.duration) + "</b>: " + decimalFormatter.to2Decimal(duration.toDouble()) + " min<br>" else "<b>" + rh.gs(R.string.rate) + "</b>: " + decimalFormatter.to2Decimal(
|
||||||
rate
|
rate
|
||||||
) + " U/h " +
|
) + " U/h " +
|
||||||
"(" + decimalFormatter.to2Decimal(rate / pump.baseBasalRate * 100.0) + "%) <br>" +
|
"(" + decimalFormatter.to2Decimal(rate / pump.baseBasalRate * 100.0) + "%) <br>" +
|
||||||
"<b>" + rh.gs(info.nightscout.core.ui.R.string.duration) + "</b>: " + decimalFormatter.to2Decimal(duration.toDouble()) + " min<br>"
|
"<b>" + rh.gs(R.string.duration) + "</b>: " + decimalFormatter.to2Decimal(duration.toDouble()) + " min<br>"
|
||||||
|
|
||||||
// smb
|
// smb
|
||||||
if (smb != 0.0) ret += "<b>" + "SMB" + "</b>: " + decimalFormatter.toPumpSupportedBolus(smb, activePlugin.activePump.pumpDescription.bolusStep) + "<br>"
|
if (smb != 0.0) ret += "<b>" + "SMB" + "</b>: " + decimalFormatter.toPumpSupportedBolus(smb, activePlugin.activePump.pumpDescription.bolusStep) + "<br>"
|
||||||
|
|
|
@ -150,7 +150,7 @@ class OpenAPSFragment : DaggerFragment(), MenuProvider {
|
||||||
binding.mealdata.text = jsonFormatter.format(determineBasalAdapter.mealDataParam)
|
binding.mealdata.text = jsonFormatter.format(determineBasalAdapter.mealDataParam)
|
||||||
binding.scriptdebugdata.text = determineBasalAdapter.scriptDebug.replace("\\s+".toRegex(), " ")
|
binding.scriptdebugdata.text = determineBasalAdapter.scriptDebug.replace("\\s+".toRegex(), " ")
|
||||||
openAPSPlugin.lastAPSResult?.inputConstraints?.let {
|
openAPSPlugin.lastAPSResult?.inputConstraints?.let {
|
||||||
binding.constraints.text = it.getReasons(aapsLogger)
|
binding.constraints.text = it.getReasons()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (openAPSPlugin.lastAPSRun != 0L) {
|
if (openAPSPlugin.lastAPSRun != 0L) {
|
||||||
|
|
|
@ -12,12 +12,13 @@ import android.view.ViewGroup
|
||||||
import androidx.core.view.MenuCompat
|
import androidx.core.view.MenuCompat
|
||||||
import androidx.core.view.MenuProvider
|
import androidx.core.view.MenuProvider
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
import dagger.android.support.DaggerFragment
|
import dagger.android.support.DaggerFragment
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.core.pump.toHtml
|
import info.nightscout.core.pump.toHtml
|
||||||
import info.nightscout.core.utils.HtmlHelper
|
import info.nightscout.core.utils.HtmlHelper
|
||||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||||
import info.nightscout.interfaces.aps.Loop
|
import info.nightscout.interfaces.aps.Loop
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
|
||||||
import info.nightscout.interfaces.utils.DecimalFormatter
|
import info.nightscout.interfaces.utils.DecimalFormatter
|
||||||
import info.nightscout.plugins.aps.R
|
import info.nightscout.plugins.aps.R
|
||||||
import info.nightscout.plugins.aps.databinding.LoopFragmentBinding
|
import info.nightscout.plugins.aps.databinding.LoopFragmentBinding
|
||||||
|
@ -44,6 +45,7 @@ class LoopFragment : DaggerFragment(), MenuProvider {
|
||||||
@Inject lateinit var loop: Loop
|
@Inject lateinit var loop: Loop
|
||||||
@Inject lateinit var dateUtil: DateUtil
|
@Inject lateinit var dateUtil: DateUtil
|
||||||
@Inject lateinit var decimalFormatter: DecimalFormatter
|
@Inject lateinit var decimalFormatter: DecimalFormatter
|
||||||
|
@Inject lateinit var injector: HasAndroidInjector
|
||||||
|
|
||||||
@Suppress("PrivatePropertyName")
|
@Suppress("PrivatePropertyName")
|
||||||
private val ID_MENU_RUN = 501
|
private val ID_MENU_RUN = 501
|
||||||
|
@ -150,12 +152,12 @@ class LoopFragment : DaggerFragment(), MenuProvider {
|
||||||
|
|
||||||
var constraints =
|
var constraints =
|
||||||
it.constraintsProcessed?.let { constraintsProcessed ->
|
it.constraintsProcessed?.let { constraintsProcessed ->
|
||||||
val allConstraints = Constraint(0.0)
|
val allConstraints = ConstraintObject(0.0, injector)
|
||||||
constraintsProcessed.rateConstraint?.let { rateConstraint -> allConstraints.copyReasons(rateConstraint) }
|
constraintsProcessed.rateConstraint?.let { rateConstraint -> allConstraints.copyReasons(rateConstraint) }
|
||||||
constraintsProcessed.smbConstraint?.let { smbConstraint -> allConstraints.copyReasons(smbConstraint) }
|
constraintsProcessed.smbConstraint?.let { smbConstraint -> allConstraints.copyReasons(smbConstraint) }
|
||||||
allConstraints.getMostLimitedReasons(aapsLogger)
|
allConstraints.getMostLimitedReasons()
|
||||||
} ?: ""
|
} ?: ""
|
||||||
constraints += loop.closedLoopEnabled?.getReasons(aapsLogger) ?: ""
|
constraints += loop.closedLoopEnabled?.getReasons() ?: ""
|
||||||
binding.constraints.text = constraints
|
binding.constraints.text = constraints
|
||||||
binding.swipeRefresh.isRefreshing = false
|
binding.swipeRefresh.isRefreshing = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import android.os.SystemClock
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.annotations.OpenForTesting
|
import info.nightscout.annotations.OpenForTesting
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.core.events.EventNewNotification
|
import info.nightscout.core.events.EventNewNotification
|
||||||
import info.nightscout.core.extensions.convertedToAbsolute
|
import info.nightscout.core.extensions.convertedToAbsolute
|
||||||
import info.nightscout.core.extensions.convertedToPercent
|
import info.nightscout.core.extensions.convertedToPercent
|
||||||
|
@ -36,7 +37,7 @@ import info.nightscout.interfaces.aps.APSResult
|
||||||
import info.nightscout.interfaces.aps.Loop
|
import info.nightscout.interfaces.aps.Loop
|
||||||
import info.nightscout.interfaces.aps.Loop.LastRun
|
import info.nightscout.interfaces.aps.Loop.LastRun
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.Constraint
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.iob.IobCobCalculator
|
import info.nightscout.interfaces.iob.IobCobCalculator
|
||||||
import info.nightscout.interfaces.logging.UserEntryLogger
|
import info.nightscout.interfaces.logging.UserEntryLogger
|
||||||
import info.nightscout.interfaces.notifications.Notification
|
import info.nightscout.interfaces.notifications.Notification
|
||||||
|
@ -91,7 +92,7 @@ class LoopPlugin @Inject constructor(
|
||||||
private val rxBus: RxBus,
|
private val rxBus: RxBus,
|
||||||
private val sp: SP,
|
private val sp: SP,
|
||||||
private val config: Config,
|
private val config: Config,
|
||||||
private val constraintChecker: Constraints,
|
private val constraintChecker: ConstraintsChecker,
|
||||||
rh: ResourceHelper,
|
rh: ResourceHelper,
|
||||||
private val profileFunction: ProfileFunction,
|
private val profileFunction: ProfileFunction,
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
|
@ -230,7 +231,7 @@ class LoopPlugin @Inject constructor(
|
||||||
if (!loopEnabled.value()) {
|
if (!loopEnabled.value()) {
|
||||||
val message = """
|
val message = """
|
||||||
${rh.gs(info.nightscout.core.ui.R.string.loop_disabled)}
|
${rh.gs(info.nightscout.core.ui.R.string.loop_disabled)}
|
||||||
${loopEnabled.getReasons(aapsLogger)}
|
${loopEnabled.getReasons()}
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
aapsLogger.debug(LTag.APS, message)
|
aapsLogger.debug(LTag.APS, message)
|
||||||
rxBus.send(EventLoopSetLastRunGui(message))
|
rxBus.send(EventLoopSetLastRunGui(message))
|
||||||
|
@ -274,11 +275,11 @@ class LoopPlugin @Inject constructor(
|
||||||
|
|
||||||
// check rate for constraints
|
// check rate for constraints
|
||||||
val resultAfterConstraints = apsResult.newAndClone(injector)
|
val resultAfterConstraints = apsResult.newAndClone(injector)
|
||||||
resultAfterConstraints.rateConstraint = Constraint(resultAfterConstraints.rate)
|
resultAfterConstraints.rateConstraint = ConstraintObject(resultAfterConstraints.rate, injector)
|
||||||
resultAfterConstraints.rate = constraintChecker.applyBasalConstraints(resultAfterConstraints.rateConstraint!!, profile).value()
|
resultAfterConstraints.rate = constraintChecker.applyBasalConstraints(resultAfterConstraints.rateConstraint!!, profile).value()
|
||||||
resultAfterConstraints.percentConstraint = Constraint(resultAfterConstraints.percent)
|
resultAfterConstraints.percentConstraint = ConstraintObject(resultAfterConstraints.percent, injector)
|
||||||
resultAfterConstraints.percent = constraintChecker.applyBasalPercentConstraints(resultAfterConstraints.percentConstraint!!, profile).value()
|
resultAfterConstraints.percent = constraintChecker.applyBasalPercentConstraints(resultAfterConstraints.percentConstraint!!, profile).value()
|
||||||
resultAfterConstraints.smbConstraint = Constraint(resultAfterConstraints.smb)
|
resultAfterConstraints.smbConstraint = ConstraintObject(resultAfterConstraints.smb, injector)
|
||||||
resultAfterConstraints.smb = constraintChecker.applyBolusConstraints(resultAfterConstraints.smbConstraint!!).value()
|
resultAfterConstraints.smb = constraintChecker.applyBolusConstraints(resultAfterConstraints.smbConstraint!!).value()
|
||||||
|
|
||||||
// safety check for multiple SMBs
|
// safety check for multiple SMBs
|
||||||
|
|
|
@ -7,7 +7,7 @@ import info.nightscout.core.extensions.plannedRemainingMinutes
|
||||||
import info.nightscout.interfaces.GlucoseUnit
|
import info.nightscout.interfaces.GlucoseUnit
|
||||||
import info.nightscout.interfaces.aps.DetermineBasalAdapter
|
import info.nightscout.interfaces.aps.DetermineBasalAdapter
|
||||||
import info.nightscout.interfaces.aps.SMBDefaults
|
import info.nightscout.interfaces.aps.SMBDefaults
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.iob.GlucoseStatus
|
import info.nightscout.interfaces.iob.GlucoseStatus
|
||||||
import info.nightscout.interfaces.iob.IobCobCalculator
|
import info.nightscout.interfaces.iob.IobCobCalculator
|
||||||
import info.nightscout.interfaces.iob.IobTotal
|
import info.nightscout.interfaces.iob.IobTotal
|
||||||
|
@ -43,7 +43,7 @@ class DetermineBasalAdapterAMAJS internal constructor(scriptReader: ScriptReader
|
||||||
private val injector: HasAndroidInjector
|
private val injector: HasAndroidInjector
|
||||||
|
|
||||||
@Inject lateinit var aapsLogger: AAPSLogger
|
@Inject lateinit var aapsLogger: AAPSLogger
|
||||||
@Inject lateinit var constraintChecker: Constraints
|
@Inject lateinit var constraintChecker: ConstraintsChecker
|
||||||
@Inject lateinit var sp: SP
|
@Inject lateinit var sp: SP
|
||||||
@Inject lateinit var profileFunction: ProfileFunction
|
@Inject lateinit var profileFunction: ProfileFunction
|
||||||
@Inject lateinit var iobCobCalculator: IobCobCalculator
|
@Inject lateinit var iobCobCalculator: IobCobCalculator
|
||||||
|
@ -107,7 +107,8 @@ class DetermineBasalAdapterAMAJS internal constructor(scriptReader: ScriptReader
|
||||||
makeParam(profile, rhino, scope),
|
makeParam(profile, rhino, scope),
|
||||||
makeParam(autosensData, rhino, scope),
|
makeParam(autosensData, rhino, scope),
|
||||||
makeParam(mealData, rhino, scope),
|
makeParam(mealData, rhino, scope),
|
||||||
setTempBasalFunctionsObj)
|
setTempBasalFunctionsObj
|
||||||
|
)
|
||||||
val jsResult = determineBasalObj.call(rhino, scope, scope, params) as NativeObject
|
val jsResult = determineBasalObj.call(rhino, scope, scope, params) as NativeObject
|
||||||
scriptDebug = LoggerCallback.scriptDebug
|
scriptDebug = LoggerCallback.scriptDebug
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package info.nightscout.plugins.aps.openAPSAMA
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.annotations.OpenForTesting
|
import info.nightscout.annotations.OpenForTesting
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.core.extensions.target
|
import info.nightscout.core.extensions.target
|
||||||
import info.nightscout.core.utils.MidnightUtils
|
import info.nightscout.core.utils.MidnightUtils
|
||||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||||
|
@ -12,7 +13,8 @@ import info.nightscout.interfaces.aps.APS
|
||||||
import info.nightscout.interfaces.aps.AutosensResult
|
import info.nightscout.interfaces.aps.AutosensResult
|
||||||
import info.nightscout.interfaces.aps.DetermineBasalAdapter
|
import info.nightscout.interfaces.aps.DetermineBasalAdapter
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.Constraint
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
|
import info.nightscout.interfaces.constraints.PluginConstraints
|
||||||
import info.nightscout.interfaces.iob.GlucoseStatusProvider
|
import info.nightscout.interfaces.iob.GlucoseStatusProvider
|
||||||
import info.nightscout.interfaces.iob.IobCobCalculator
|
import info.nightscout.interfaces.iob.IobCobCalculator
|
||||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||||
|
@ -46,7 +48,7 @@ class OpenAPSAMAPlugin @Inject constructor(
|
||||||
injector: HasAndroidInjector,
|
injector: HasAndroidInjector,
|
||||||
aapsLogger: AAPSLogger,
|
aapsLogger: AAPSLogger,
|
||||||
private val rxBus: RxBus,
|
private val rxBus: RxBus,
|
||||||
private val constraintChecker: Constraints,
|
private val constraintChecker: ConstraintsChecker,
|
||||||
rh: ResourceHelper,
|
rh: ResourceHelper,
|
||||||
private val profileFunction: ProfileFunction,
|
private val profileFunction: ProfileFunction,
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
|
@ -69,7 +71,7 @@ class OpenAPSAMAPlugin @Inject constructor(
|
||||||
.preferencesId(R.xml.pref_openapsama)
|
.preferencesId(R.xml.pref_openapsama)
|
||||||
.description(R.string.description_ama),
|
.description(R.string.description_ama),
|
||||||
aapsLogger, rh, injector
|
aapsLogger, rh, injector
|
||||||
), APS, Constraints {
|
), APS, PluginConstraints {
|
||||||
|
|
||||||
// last values
|
// last values
|
||||||
override var lastAPSRun: Long = 0
|
override var lastAPSRun: Long = 0
|
||||||
|
@ -114,7 +116,7 @@ class OpenAPSAMAPlugin @Inject constructor(
|
||||||
aapsLogger.debug(LTag.APS, rh.gs(R.string.openapsma_no_glucose_data))
|
aapsLogger.debug(LTag.APS, rh.gs(R.string.openapsma_no_glucose_data))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val inputConstraints = Constraint(0.0) // fake. only for collecting all results
|
val inputConstraints = ConstraintObject(0.0, injector) // fake. only for collecting all results
|
||||||
val maxBasal = constraintChecker.getMaxBasalAllowed(profile).also {
|
val maxBasal = constraintChecker.getMaxBasalAllowed(profile).also {
|
||||||
inputConstraints.copyReasons(it)
|
inputConstraints.copyReasons(it)
|
||||||
}.value()
|
}.value()
|
||||||
|
@ -237,8 +239,8 @@ class OpenAPSAMAPlugin @Inject constructor(
|
||||||
override fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> {
|
override fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> {
|
||||||
if (isEnabled()) {
|
if (isEnabled()) {
|
||||||
val maxIobPref: Double = sp.getDouble(R.string.key_openapsma_max_iob, 1.5)
|
val maxIobPref: Double = sp.getDouble(R.string.key_openapsma_max_iob, 1.5)
|
||||||
maxIob.setIfSmaller(aapsLogger, maxIobPref, rh.gs(R.string.limiting_iob, maxIobPref, rh.gs(R.string.maxvalueinpreferences)), this)
|
maxIob.setIfSmaller(maxIobPref, rh.gs(R.string.limiting_iob, maxIobPref, rh.gs(R.string.maxvalueinpreferences)), this)
|
||||||
maxIob.setIfSmaller(aapsLogger, hardLimits.maxIobAMA(), rh.gs(R.string.limiting_iob, hardLimits.maxIobAMA(), rh.gs(R.string.hardlimit)), this)
|
maxIob.setIfSmaller(hardLimits.maxIobAMA(), rh.gs(R.string.limiting_iob, hardLimits.maxIobAMA(), rh.gs(R.string.hardlimit)), this)
|
||||||
}
|
}
|
||||||
return maxIob
|
return maxIob
|
||||||
}
|
}
|
||||||
|
@ -250,27 +252,26 @@ class OpenAPSAMAPlugin @Inject constructor(
|
||||||
maxBasal = profile.getMaxDailyBasal()
|
maxBasal = profile.getMaxDailyBasal()
|
||||||
absoluteRate.addReason(rh.gs(R.string.increasing_max_basal), this)
|
absoluteRate.addReason(rh.gs(R.string.increasing_max_basal), this)
|
||||||
}
|
}
|
||||||
absoluteRate.setIfSmaller(aapsLogger, maxBasal, rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, maxBasal, rh.gs(R.string.maxvalueinpreferences)), this)
|
absoluteRate.setIfSmaller(maxBasal, rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, maxBasal, rh.gs(R.string.maxvalueinpreferences)), this)
|
||||||
|
|
||||||
// Check percentRate but absolute rate too, because we know real current basal in pump
|
// Check percentRate but absolute rate too, because we know real current basal in pump
|
||||||
val maxBasalMultiplier = sp.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4.0)
|
val maxBasalMultiplier = sp.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4.0)
|
||||||
val maxFromBasalMultiplier = floor(maxBasalMultiplier * profile.getBasal() * 100) / 100
|
val maxFromBasalMultiplier = floor(maxBasalMultiplier * profile.getBasal() * 100) / 100
|
||||||
absoluteRate.setIfSmaller(
|
absoluteRate.setIfSmaller(
|
||||||
aapsLogger,
|
|
||||||
maxFromBasalMultiplier,
|
maxFromBasalMultiplier,
|
||||||
rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, maxFromBasalMultiplier, rh.gs(R.string.max_basal_multiplier)),
|
rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, maxFromBasalMultiplier, rh.gs(R.string.max_basal_multiplier)),
|
||||||
this
|
this
|
||||||
)
|
)
|
||||||
val maxBasalFromDaily = sp.getDouble(R.string.key_openapsama_max_daily_safety_multiplier, 3.0)
|
val maxBasalFromDaily = sp.getDouble(R.string.key_openapsama_max_daily_safety_multiplier, 3.0)
|
||||||
val maxFromDaily = floor(profile.getMaxDailyBasal() * maxBasalFromDaily * 100) / 100
|
val maxFromDaily = floor(profile.getMaxDailyBasal() * maxBasalFromDaily * 100) / 100
|
||||||
absoluteRate.setIfSmaller(aapsLogger, maxFromDaily, rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, maxFromDaily, rh.gs(R.string.max_daily_basal_multiplier)), this)
|
absoluteRate.setIfSmaller(maxFromDaily, rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, maxFromDaily, rh.gs(R.string.max_daily_basal_multiplier)), this)
|
||||||
}
|
}
|
||||||
return absoluteRate
|
return absoluteRate
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isAutosensModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isAutosensModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
val enabled = sp.getBoolean(R.string.key_openapsama_use_autosens, false)
|
val enabled = sp.getBoolean(R.string.key_openapsama_use_autosens, false)
|
||||||
if (!enabled) value.set(aapsLogger, false, rh.gs(R.string.autosens_disabled_in_preferences), this)
|
if (!enabled) value.set(false, rh.gs(R.string.autosens_disabled_in_preferences), this)
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,7 +7,7 @@ import info.nightscout.core.extensions.plannedRemainingMinutes
|
||||||
import info.nightscout.interfaces.GlucoseUnit
|
import info.nightscout.interfaces.GlucoseUnit
|
||||||
import info.nightscout.interfaces.aps.DetermineBasalAdapter
|
import info.nightscout.interfaces.aps.DetermineBasalAdapter
|
||||||
import info.nightscout.interfaces.aps.SMBDefaults
|
import info.nightscout.interfaces.aps.SMBDefaults
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.iob.GlucoseStatus
|
import info.nightscout.interfaces.iob.GlucoseStatus
|
||||||
import info.nightscout.interfaces.iob.IobCobCalculator
|
import info.nightscout.interfaces.iob.IobCobCalculator
|
||||||
import info.nightscout.interfaces.iob.IobTotal
|
import info.nightscout.interfaces.iob.IobTotal
|
||||||
|
@ -42,7 +42,7 @@ import javax.inject.Inject
|
||||||
class DetermineBasalAdapterSMBJS internal constructor(private val scriptReader: ScriptReader, private val injector: HasAndroidInjector) : DetermineBasalAdapter {
|
class DetermineBasalAdapterSMBJS internal constructor(private val scriptReader: ScriptReader, private val injector: HasAndroidInjector) : DetermineBasalAdapter {
|
||||||
|
|
||||||
@Inject lateinit var aapsLogger: AAPSLogger
|
@Inject lateinit var aapsLogger: AAPSLogger
|
||||||
@Inject lateinit var constraintChecker: Constraints
|
@Inject lateinit var constraintChecker: ConstraintsChecker
|
||||||
@Inject lateinit var sp: SP
|
@Inject lateinit var sp: SP
|
||||||
@Inject lateinit var profileFunction: ProfileFunction
|
@Inject lateinit var profileFunction: ProfileFunction
|
||||||
@Inject lateinit var iobCobCalculator: IobCobCalculator
|
@Inject lateinit var iobCobCalculator: IobCobCalculator
|
||||||
|
|
|
@ -4,6 +4,7 @@ import android.content.Context
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
import androidx.preference.SwitchPreference
|
import androidx.preference.SwitchPreference
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.core.extensions.target
|
import info.nightscout.core.extensions.target
|
||||||
import info.nightscout.core.utils.MidnightUtils
|
import info.nightscout.core.utils.MidnightUtils
|
||||||
import info.nightscout.database.ValueWrapper
|
import info.nightscout.database.ValueWrapper
|
||||||
|
@ -14,7 +15,8 @@ import info.nightscout.interfaces.aps.DetermineBasalAdapter
|
||||||
import info.nightscout.interfaces.aps.SMBDefaults
|
import info.nightscout.interfaces.aps.SMBDefaults
|
||||||
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
|
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.Constraint
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
|
import info.nightscout.interfaces.constraints.PluginConstraints
|
||||||
import info.nightscout.interfaces.iob.GlucoseStatusProvider
|
import info.nightscout.interfaces.iob.GlucoseStatusProvider
|
||||||
import info.nightscout.interfaces.iob.IobCobCalculator
|
import info.nightscout.interfaces.iob.IobCobCalculator
|
||||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||||
|
@ -44,7 +46,7 @@ open class OpenAPSSMBPlugin @Inject constructor(
|
||||||
injector: HasAndroidInjector,
|
injector: HasAndroidInjector,
|
||||||
aapsLogger: AAPSLogger,
|
aapsLogger: AAPSLogger,
|
||||||
private val rxBus: RxBus,
|
private val rxBus: RxBus,
|
||||||
private val constraintChecker: Constraints,
|
private val constraintChecker: ConstraintsChecker,
|
||||||
rh: ResourceHelper,
|
rh: ResourceHelper,
|
||||||
private val profileFunction: ProfileFunction,
|
private val profileFunction: ProfileFunction,
|
||||||
val context: Context,
|
val context: Context,
|
||||||
|
@ -69,7 +71,7 @@ open class OpenAPSSMBPlugin @Inject constructor(
|
||||||
.description(R.string.description_smb)
|
.description(R.string.description_smb)
|
||||||
.setDefault(),
|
.setDefault(),
|
||||||
aapsLogger, rh, injector
|
aapsLogger, rh, injector
|
||||||
), APS, Constraints {
|
), APS, PluginConstraints {
|
||||||
|
|
||||||
// DynamicISF specific
|
// DynamicISF specific
|
||||||
var tdd1D: Double? = null
|
var tdd1D: Double? = null
|
||||||
|
@ -77,7 +79,7 @@ open class OpenAPSSMBPlugin @Inject constructor(
|
||||||
var tddLast24H: Double? = null
|
var tddLast24H: Double? = null
|
||||||
var tddLast4H: Double? = null
|
var tddLast4H: Double? = null
|
||||||
var tddLast8to4H: Double? = null
|
var tddLast8to4H: Double? = null
|
||||||
var dynIsfEnabled: Constraint<Boolean> = Constraint(false)
|
var dynIsfEnabled: Constraint<Boolean> = ConstraintObject(false, injector)
|
||||||
|
|
||||||
// last values
|
// last values
|
||||||
override var lastAPSRun: Long = 0
|
override var lastAPSRun: Long = 0
|
||||||
|
@ -129,7 +131,7 @@ open class OpenAPSSMBPlugin @Inject constructor(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val inputConstraints = Constraint(0.0) // fake. only for collecting all results
|
val inputConstraints = ConstraintObject(0.0, injector) // fake. only for collecting all results
|
||||||
val maxBasal = constraintChecker.getMaxBasalAllowed(profile).also {
|
val maxBasal = constraintChecker.getMaxBasalAllowed(profile).also {
|
||||||
inputConstraints.copyReasons(it)
|
inputConstraints.copyReasons(it)
|
||||||
}.value()
|
}.value()
|
||||||
|
@ -207,19 +209,19 @@ open class OpenAPSSMBPlugin @Inject constructor(
|
||||||
val iobArray = iobCobCalculator.calculateIobArrayForSMB(lastAutosensResult, SMBDefaults.exercise_mode, SMBDefaults.half_basal_exercise_target, isTempTarget)
|
val iobArray = iobCobCalculator.calculateIobArrayForSMB(lastAutosensResult, SMBDefaults.exercise_mode, SMBDefaults.half_basal_exercise_target, isTempTarget)
|
||||||
profiler.log(LTag.APS, "calculateIobArrayInDia()", startPart)
|
profiler.log(LTag.APS, "calculateIobArrayInDia()", startPart)
|
||||||
startPart = System.currentTimeMillis()
|
startPart = System.currentTimeMillis()
|
||||||
val smbAllowed = Constraint(!tempBasalFallback).also {
|
val smbAllowed = ConstraintObject(!tempBasalFallback, injector).also {
|
||||||
constraintChecker.isSMBModeEnabled(it)
|
constraintChecker.isSMBModeEnabled(it)
|
||||||
inputConstraints.copyReasons(it)
|
inputConstraints.copyReasons(it)
|
||||||
}
|
}
|
||||||
val advancedFiltering = Constraint(!tempBasalFallback).also {
|
val advancedFiltering = ConstraintObject(!tempBasalFallback, injector).also {
|
||||||
constraintChecker.isAdvancedFilteringEnabled(it)
|
constraintChecker.isAdvancedFilteringEnabled(it)
|
||||||
inputConstraints.copyReasons(it)
|
inputConstraints.copyReasons(it)
|
||||||
}
|
}
|
||||||
val uam = Constraint(true).also {
|
val uam = ConstraintObject(true, injector).also {
|
||||||
constraintChecker.isUAMEnabled(it)
|
constraintChecker.isUAMEnabled(it)
|
||||||
inputConstraints.copyReasons(it)
|
inputConstraints.copyReasons(it)
|
||||||
}
|
}
|
||||||
dynIsfEnabled = Constraint(true).also {
|
dynIsfEnabled = ConstraintObject(true, injector).also {
|
||||||
constraintChecker.isDynIsfModeEnabled(it)
|
constraintChecker.isDynIsfModeEnabled(it)
|
||||||
inputConstraints.copyReasons(it)
|
inputConstraints.copyReasons(it)
|
||||||
}
|
}
|
||||||
|
@ -239,12 +241,12 @@ open class OpenAPSSMBPlugin @Inject constructor(
|
||||||
|
|
||||||
if (tdd1D == null || tdd7D == null || tddLast4H == null || tddLast8to4H == null || tddLast24H == null) {
|
if (tdd1D == null || tdd7D == null || tddLast4H == null || tddLast8to4H == null || tddLast24H == null) {
|
||||||
inputConstraints.copyReasons(
|
inputConstraints.copyReasons(
|
||||||
Constraint(false).also {
|
ConstraintObject(false, injector).also {
|
||||||
it.set(aapsLogger, false, rh.gs(R.string.fallback_smb_no_tdd), this)
|
it.set(false, rh.gs(R.string.fallback_smb_no_tdd), this)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
inputConstraints.copyReasons(
|
inputConstraints.copyReasons(
|
||||||
Constraint(false).apply { set(aapsLogger, true, "tdd1D=$tdd1D tdd7D=$tdd7D tddLast4H=$tddLast4H tddLast8to4H=$tddLast8to4H tddLast24H=$tddLast24H", this) }
|
ConstraintObject(false, injector).apply { set(true, "tdd1D=$tdd1D tdd7D=$tdd7D tddLast4H=$tddLast4H tddLast8to4H=$tddLast8to4H tddLast24H=$tddLast24H", this) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,15 +295,15 @@ open class OpenAPSSMBPlugin @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isSuperBolusEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isSuperBolusEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
value.set(aapsLogger, false)
|
value.set(false)
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> {
|
override fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> {
|
||||||
if (isEnabled()) {
|
if (isEnabled()) {
|
||||||
val maxIobPref: Double = sp.getDouble(R.string.key_openapssmb_max_iob, 3.0)
|
val maxIobPref: Double = sp.getDouble(R.string.key_openapssmb_max_iob, 3.0)
|
||||||
maxIob.setIfSmaller(aapsLogger, maxIobPref, rh.gs(R.string.limiting_iob, maxIobPref, rh.gs(R.string.maxvalueinpreferences)), this)
|
maxIob.setIfSmaller(maxIobPref, rh.gs(R.string.limiting_iob, maxIobPref, rh.gs(R.string.maxvalueinpreferences)), this)
|
||||||
maxIob.setIfSmaller(aapsLogger, hardLimits.maxIobSMB(), rh.gs(R.string.limiting_iob, hardLimits.maxIobSMB(), rh.gs(R.string.hardlimit)), this)
|
maxIob.setIfSmaller(hardLimits.maxIobSMB(), rh.gs(R.string.limiting_iob, hardLimits.maxIobSMB(), rh.gs(R.string.hardlimit)), this)
|
||||||
}
|
}
|
||||||
return maxIob
|
return maxIob
|
||||||
}
|
}
|
||||||
|
@ -313,39 +315,38 @@ open class OpenAPSSMBPlugin @Inject constructor(
|
||||||
maxBasal = profile.getMaxDailyBasal()
|
maxBasal = profile.getMaxDailyBasal()
|
||||||
absoluteRate.addReason(rh.gs(R.string.increasing_max_basal), this)
|
absoluteRate.addReason(rh.gs(R.string.increasing_max_basal), this)
|
||||||
}
|
}
|
||||||
absoluteRate.setIfSmaller(aapsLogger, maxBasal, rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, maxBasal, rh.gs(R.string.maxvalueinpreferences)), this)
|
absoluteRate.setIfSmaller(maxBasal, rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, maxBasal, rh.gs(R.string.maxvalueinpreferences)), this)
|
||||||
|
|
||||||
// Check percentRate but absolute rate too, because we know real current basal in pump
|
// Check percentRate but absolute rate too, because we know real current basal in pump
|
||||||
val maxBasalMultiplier = sp.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4.0)
|
val maxBasalMultiplier = sp.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4.0)
|
||||||
val maxFromBasalMultiplier = floor(maxBasalMultiplier * profile.getBasal() * 100) / 100
|
val maxFromBasalMultiplier = floor(maxBasalMultiplier * profile.getBasal() * 100) / 100
|
||||||
absoluteRate.setIfSmaller(
|
absoluteRate.setIfSmaller(
|
||||||
aapsLogger,
|
|
||||||
maxFromBasalMultiplier,
|
maxFromBasalMultiplier,
|
||||||
rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, maxFromBasalMultiplier, rh.gs(R.string.max_basal_multiplier)),
|
rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, maxFromBasalMultiplier, rh.gs(R.string.max_basal_multiplier)),
|
||||||
this
|
this
|
||||||
)
|
)
|
||||||
val maxBasalFromDaily = sp.getDouble(R.string.key_openapsama_max_daily_safety_multiplier, 3.0)
|
val maxBasalFromDaily = sp.getDouble(R.string.key_openapsama_max_daily_safety_multiplier, 3.0)
|
||||||
val maxFromDaily = floor(profile.getMaxDailyBasal() * maxBasalFromDaily * 100) / 100
|
val maxFromDaily = floor(profile.getMaxDailyBasal() * maxBasalFromDaily * 100) / 100
|
||||||
absoluteRate.setIfSmaller(aapsLogger, maxFromDaily, rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, maxFromDaily, rh.gs(R.string.max_daily_basal_multiplier)), this)
|
absoluteRate.setIfSmaller(maxFromDaily, rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, maxFromDaily, rh.gs(R.string.max_daily_basal_multiplier)), this)
|
||||||
}
|
}
|
||||||
return absoluteRate
|
return absoluteRate
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isSMBModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isSMBModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
val enabled = sp.getBoolean(R.string.key_use_smb, false)
|
val enabled = sp.getBoolean(R.string.key_use_smb, false)
|
||||||
if (!enabled) value.set(aapsLogger, false, rh.gs(R.string.smb_disabled_in_preferences), this)
|
if (!enabled) value.set(false, rh.gs(R.string.smb_disabled_in_preferences), this)
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isUAMEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isUAMEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
val enabled = sp.getBoolean(R.string.key_use_uam, false)
|
val enabled = sp.getBoolean(R.string.key_use_uam, false)
|
||||||
if (!enabled) value.set(aapsLogger, false, rh.gs(R.string.uam_disabled_in_preferences), this)
|
if (!enabled) value.set(false, rh.gs(R.string.uam_disabled_in_preferences), this)
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isAutosensModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isAutosensModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
val enabled = sp.getBoolean(R.string.key_openapsama_use_autosens, false)
|
val enabled = sp.getBoolean(R.string.key_openapsama_use_autosens, false)
|
||||||
if (!enabled) value.set(aapsLogger, false, rh.gs(R.string.autosens_disabled_in_preferences), this)
|
if (!enabled) value.set(false, rh.gs(R.string.autosens_disabled_in_preferences), this)
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import info.nightscout.annotations.OpenForTesting
|
||||||
import info.nightscout.database.impl.AppRepository
|
import info.nightscout.database.impl.AppRepository
|
||||||
import info.nightscout.interfaces.aps.DetermineBasalAdapter
|
import info.nightscout.interfaces.aps.DetermineBasalAdapter
|
||||||
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
|
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.iob.GlucoseStatusProvider
|
import info.nightscout.interfaces.iob.GlucoseStatusProvider
|
||||||
import info.nightscout.interfaces.iob.IobCobCalculator
|
import info.nightscout.interfaces.iob.IobCobCalculator
|
||||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||||
|
@ -32,7 +32,7 @@ class OpenAPSSMBDynamicISFPlugin @Inject constructor(
|
||||||
injector: HasAndroidInjector,
|
injector: HasAndroidInjector,
|
||||||
aapsLogger: AAPSLogger,
|
aapsLogger: AAPSLogger,
|
||||||
rxBus: RxBus,
|
rxBus: RxBus,
|
||||||
constraintChecker: Constraints,
|
constraintChecker: ConstraintsChecker,
|
||||||
rh: ResourceHelper,
|
rh: ResourceHelper,
|
||||||
profileFunction: ProfileFunction,
|
profileFunction: ProfileFunction,
|
||||||
context: Context,
|
context: Context,
|
||||||
|
|
|
@ -2,11 +2,11 @@ package info.nightscout.plugins.aps.loop
|
||||||
|
|
||||||
import dagger.android.AndroidInjector
|
import dagger.android.AndroidInjector
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.core.utils.JsonHelper.safeGetDouble
|
import info.nightscout.core.utils.JsonHelper.safeGetDouble
|
||||||
import info.nightscout.database.entities.TemporaryBasal
|
import info.nightscout.database.entities.TemporaryBasal
|
||||||
import info.nightscout.interfaces.aps.APSResult
|
import info.nightscout.interfaces.aps.APSResult
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
|
||||||
import info.nightscout.interfaces.pump.defs.PumpType
|
import info.nightscout.interfaces.pump.defs.PumpType
|
||||||
import info.nightscout.sharedtests.TestBaseWithProfile
|
import info.nightscout.sharedtests.TestBaseWithProfile
|
||||||
import org.junit.jupiter.api.Assertions
|
import org.junit.jupiter.api.Assertions
|
||||||
|
@ -18,11 +18,11 @@ import org.mockito.Mockito.`when`
|
||||||
|
|
||||||
class APSResultTest : TestBaseWithProfile() {
|
class APSResultTest : TestBaseWithProfile() {
|
||||||
|
|
||||||
@Mock lateinit var constraints: Constraints
|
@Mock lateinit var constraintsChecker: ConstraintsChecker
|
||||||
|
|
||||||
private val injector = HasAndroidInjector { AndroidInjector { } }
|
private val injector = HasAndroidInjector { AndroidInjector { } }
|
||||||
|
|
||||||
private var closedLoopEnabled = Constraint(false)
|
private var closedLoopEnabled = ConstraintObject(false, injector)
|
||||||
|
|
||||||
private fun APSResult.percent(percent: Int): APSResult {
|
private fun APSResult.percent(percent: Int): APSResult {
|
||||||
this.percent = percent
|
this.percent = percent
|
||||||
|
@ -55,7 +55,7 @@ class APSResultTest : TestBaseWithProfile() {
|
||||||
val apsResult = info.nightscout.plugins.aps.APSResultObject { AndroidInjector { } }
|
val apsResult = info.nightscout.plugins.aps.APSResultObject { AndroidInjector { } }
|
||||||
.also {
|
.also {
|
||||||
it.aapsLogger = aapsLogger
|
it.aapsLogger = aapsLogger
|
||||||
it.constraintChecker = constraints
|
it.constraintChecker = constraintsChecker
|
||||||
it.sp = sp
|
it.sp = sp
|
||||||
it.activePlugin = activePlugin
|
it.activePlugin = activePlugin
|
||||||
it.iobCobCalculator = iobCobCalculator
|
it.iobCobCalculator = iobCobCalculator
|
||||||
|
@ -70,7 +70,7 @@ class APSResultTest : TestBaseWithProfile() {
|
||||||
apsResult.usePercent(true)
|
apsResult.usePercent(true)
|
||||||
|
|
||||||
// closed loop mode return original request
|
// closed loop mode return original request
|
||||||
closedLoopEnabled.set(aapsLogger, true)
|
closedLoopEnabled.set(true)
|
||||||
`when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(null)
|
`when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(null)
|
||||||
apsResult.tempBasalRequested(false)
|
apsResult.tempBasalRequested(false)
|
||||||
Assertions.assertEquals(false, apsResult.isChangeRequested)
|
Assertions.assertEquals(false, apsResult.isChangeRequested)
|
||||||
|
@ -78,7 +78,7 @@ class APSResultTest : TestBaseWithProfile() {
|
||||||
Assertions.assertEquals(true, apsResult.isChangeRequested)
|
Assertions.assertEquals(true, apsResult.isChangeRequested)
|
||||||
|
|
||||||
// open loop
|
// open loop
|
||||||
closedLoopEnabled.set(aapsLogger, false)
|
closedLoopEnabled.set(false)
|
||||||
// no change requested
|
// no change requested
|
||||||
`when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(null)
|
`when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(null)
|
||||||
apsResult.tempBasalRequested(false)
|
apsResult.tempBasalRequested(false)
|
||||||
|
@ -184,7 +184,7 @@ class APSResultTest : TestBaseWithProfile() {
|
||||||
apsResult.usePercent(false)
|
apsResult.usePercent(false)
|
||||||
|
|
||||||
// open loop
|
// open loop
|
||||||
closedLoopEnabled.set(aapsLogger, false)
|
closedLoopEnabled.set(false)
|
||||||
// request 100% when no temp is running
|
// request 100% when no temp is running
|
||||||
`when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(null)
|
`when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(null)
|
||||||
apsResult.tempBasalRequested(true).rate(1.0).duration(30)
|
apsResult.tempBasalRequested(true).rate(1.0).duration(30)
|
||||||
|
@ -296,7 +296,7 @@ class APSResultTest : TestBaseWithProfile() {
|
||||||
val apsResult = info.nightscout.plugins.aps.APSResultObject { AndroidInjector { } }
|
val apsResult = info.nightscout.plugins.aps.APSResultObject { AndroidInjector { } }
|
||||||
.also {
|
.also {
|
||||||
it.aapsLogger = aapsLogger
|
it.aapsLogger = aapsLogger
|
||||||
it.constraintChecker = constraints
|
it.constraintChecker = constraintsChecker
|
||||||
it.sp = sp
|
it.sp = sp
|
||||||
it.activePlugin = activePlugin
|
it.activePlugin = activePlugin
|
||||||
it.iobCobCalculator = iobCobCalculator
|
it.iobCobCalculator = iobCobCalculator
|
||||||
|
@ -309,11 +309,11 @@ class APSResultTest : TestBaseWithProfile() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun jsonTest() {
|
@Test fun jsonTest() {
|
||||||
closedLoopEnabled.set(aapsLogger, true)
|
closedLoopEnabled.set(true)
|
||||||
val apsResult = info.nightscout.plugins.aps.APSResultObject { AndroidInjector { } }
|
val apsResult = info.nightscout.plugins.aps.APSResultObject { AndroidInjector { } }
|
||||||
.also {
|
.also {
|
||||||
it.aapsLogger = aapsLogger
|
it.aapsLogger = aapsLogger
|
||||||
it.constraintChecker = constraints
|
it.constraintChecker = constraintsChecker
|
||||||
it.sp = sp
|
it.sp = sp
|
||||||
it.activePlugin = activePlugin
|
it.activePlugin = activePlugin
|
||||||
it.iobCobCalculator = iobCobCalculator
|
it.iobCobCalculator = iobCobCalculator
|
||||||
|
@ -328,7 +328,7 @@ class APSResultTest : TestBaseWithProfile() {
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
fun prepare() {
|
fun prepare() {
|
||||||
`when`(constraints.isClosedLoopAllowed(anyObject())).thenReturn(closedLoopEnabled)
|
`when`(constraintsChecker.isClosedLoopAllowed(anyObject())).thenReturn(closedLoopEnabled)
|
||||||
`when`(sp.getDouble(ArgumentMatchers.anyInt(), ArgumentMatchers.anyDouble())).thenReturn(30.0)
|
`when`(sp.getDouble(ArgumentMatchers.anyInt(), ArgumentMatchers.anyDouble())).thenReturn(30.0)
|
||||||
`when`(profileFunction.getProfile()).thenReturn(validProfile)
|
`when`(profileFunction.getProfile()).thenReturn(validProfile)
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ dependencies {
|
||||||
implementation project(':database:impl')
|
implementation project(':database:impl')
|
||||||
|
|
||||||
testImplementation project(':app-wear-shared:shared-tests')
|
testImplementation project(':app-wear-shared:shared-tests')
|
||||||
|
testImplementation project(':app-wear-shared:shared-impl')
|
||||||
testImplementation project(':implementation')
|
testImplementation project(':implementation')
|
||||||
testImplementation project(':plugins:main')
|
testImplementation project(':plugins:main')
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ import info.nightscout.interfaces.GlucoseUnit
|
||||||
import info.nightscout.interfaces.aps.Loop
|
import info.nightscout.interfaces.aps.Loop
|
||||||
import info.nightscout.interfaces.automation.Automation
|
import info.nightscout.interfaces.automation.Automation
|
||||||
import info.nightscout.interfaces.automation.AutomationEvent
|
import info.nightscout.interfaces.automation.AutomationEvent
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||||
import info.nightscout.interfaces.plugin.PluginBase
|
import info.nightscout.interfaces.plugin.PluginBase
|
||||||
import info.nightscout.interfaces.plugin.PluginDescription
|
import info.nightscout.interfaces.plugin.PluginDescription
|
||||||
|
@ -87,7 +87,7 @@ class AutomationPlugin @Inject constructor(
|
||||||
private val fabricPrivacy: FabricPrivacy,
|
private val fabricPrivacy: FabricPrivacy,
|
||||||
private val loop: Loop,
|
private val loop: Loop,
|
||||||
private val rxBus: RxBus,
|
private val rxBus: RxBus,
|
||||||
private val constraintChecker: Constraints,
|
private val constraintChecker: ConstraintsChecker,
|
||||||
aapsLogger: AAPSLogger,
|
aapsLogger: AAPSLogger,
|
||||||
private val aapsSchedulers: AapsSchedulers,
|
private val aapsSchedulers: AapsSchedulers,
|
||||||
private val config: Config,
|
private val config: Config,
|
||||||
|
@ -244,7 +244,7 @@ class AutomationPlugin @Inject constructor(
|
||||||
}
|
}
|
||||||
val enabled = constraintChecker.isAutomationEnabled()
|
val enabled = constraintChecker.isAutomationEnabled()
|
||||||
if (!enabled.value()) {
|
if (!enabled.value()) {
|
||||||
executionLog.add(enabled.getMostLimitedReasons(aapsLogger))
|
executionLog.add(enabled.getMostLimitedReasons())
|
||||||
rxBus.send(EventAutomationUpdateGui())
|
rxBus.send(EventAutomationUpdateGui())
|
||||||
commonEventsEnabled = false
|
commonEventsEnabled = false
|
||||||
}
|
}
|
||||||
|
@ -413,7 +413,7 @@ class AutomationPlugin @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate reminder via [info.nightscout.interfaces.utils.TimerUtil]
|
* Generate reminder via [info.nightscout.automation.ui.TimerUtil]
|
||||||
*
|
*
|
||||||
* @param seconds seconds to the future
|
* @param seconds seconds to the future
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -10,7 +10,6 @@ import info.nightscout.automation.triggers.TriggerConnectorTest
|
||||||
import info.nightscout.automation.triggers.TriggerDummy
|
import info.nightscout.automation.triggers.TriggerDummy
|
||||||
import info.nightscout.interfaces.ConfigBuilder
|
import info.nightscout.interfaces.ConfigBuilder
|
||||||
import info.nightscout.interfaces.aps.Loop
|
import info.nightscout.interfaces.aps.Loop
|
||||||
import info.nightscout.rx.bus.RxBus
|
|
||||||
import info.nightscout.shared.interfaces.ResourceHelper
|
import info.nightscout.shared.interfaces.ResourceHelper
|
||||||
import info.nightscout.sharedtests.TestBase
|
import info.nightscout.sharedtests.TestBase
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
@ -36,7 +35,7 @@ class AutomationEventTest : TestBase() {
|
||||||
it.loopPlugin = loopPlugin
|
it.loopPlugin = loopPlugin
|
||||||
it.rh = rh
|
it.rh = rh
|
||||||
it.configBuilder = configBuilder
|
it.configBuilder = configBuilder
|
||||||
it.rxBus = RxBus(aapsSchedulers, aapsLogger)
|
it.rxBus = rxBus
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,13 +10,13 @@ import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||||
import info.nightscout.interfaces.Config
|
import info.nightscout.interfaces.Config
|
||||||
import info.nightscout.interfaces.GlucoseUnit
|
import info.nightscout.interfaces.GlucoseUnit
|
||||||
import info.nightscout.interfaces.aps.Loop
|
import info.nightscout.interfaces.aps.Loop
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||||
import info.nightscout.interfaces.profile.ProfileFunction
|
import info.nightscout.interfaces.profile.ProfileFunction
|
||||||
import info.nightscout.rx.bus.RxBus
|
|
||||||
import info.nightscout.shared.interfaces.ResourceHelper
|
import info.nightscout.shared.interfaces.ResourceHelper
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
import info.nightscout.shared.utils.DateUtil
|
import info.nightscout.shared.utils.DateUtil
|
||||||
|
import info.nightscout.shared.utils.DateUtilImpl
|
||||||
import info.nightscout.sharedtests.TestBase
|
import info.nightscout.sharedtests.TestBase
|
||||||
import org.junit.jupiter.api.Assertions
|
import org.junit.jupiter.api.Assertions
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
|
@ -32,8 +32,7 @@ class BolusTimerImplTest : TestBase() {
|
||||||
@Mock lateinit var sp: SP
|
@Mock lateinit var sp: SP
|
||||||
@Mock lateinit var fabricPrivacy: FabricPrivacy
|
@Mock lateinit var fabricPrivacy: FabricPrivacy
|
||||||
@Mock lateinit var loop: Loop
|
@Mock lateinit var loop: Loop
|
||||||
@Mock lateinit var rxBus: RxBus
|
@Mock lateinit var constraintChecker: ConstraintsChecker
|
||||||
@Mock lateinit var constraintChecker: Constraints
|
|
||||||
@Mock lateinit var config: Config
|
@Mock lateinit var config: Config
|
||||||
@Mock lateinit var locationServiceHelper: LocationServiceHelper
|
@Mock lateinit var locationServiceHelper: LocationServiceHelper
|
||||||
@Mock lateinit var activePlugin: ActivePlugin
|
@Mock lateinit var activePlugin: ActivePlugin
|
||||||
|
@ -49,16 +48,17 @@ class BolusTimerImplTest : TestBase() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private lateinit var dateUtil: DateUtil
|
private lateinit var dateUtil: DateUtil
|
||||||
|
|
||||||
private lateinit var automationPlugin: AutomationPlugin
|
private lateinit var automationPlugin: AutomationPlugin
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
fun init() {
|
fun init() {
|
||||||
Mockito.`when`(rh.gs(anyInt())).thenReturn("")
|
Mockito.`when`(rh.gs(anyInt())).thenReturn("")
|
||||||
Mockito.`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL)
|
Mockito.`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL)
|
||||||
dateUtil = DateUtil(context)
|
dateUtil = DateUtilImpl(context)
|
||||||
automationPlugin = AutomationPlugin(injector, rh, context, sp, fabricPrivacy, loop, rxBus, constraintChecker, aapsLogger, aapsSchedulers, config, locationServiceHelper, dateUtil,
|
automationPlugin = AutomationPlugin(
|
||||||
activePlugin, timerUtil)
|
injector, rh, context, sp, fabricPrivacy, loop, rxBus, constraintChecker, aapsLogger, aapsSchedulers, config, locationServiceHelper, dateUtil,
|
||||||
|
activePlugin, timerUtil
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -10,13 +10,13 @@ import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||||
import info.nightscout.interfaces.Config
|
import info.nightscout.interfaces.Config
|
||||||
import info.nightscout.interfaces.GlucoseUnit
|
import info.nightscout.interfaces.GlucoseUnit
|
||||||
import info.nightscout.interfaces.aps.Loop
|
import info.nightscout.interfaces.aps.Loop
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||||
import info.nightscout.interfaces.profile.ProfileFunction
|
import info.nightscout.interfaces.profile.ProfileFunction
|
||||||
import info.nightscout.rx.bus.RxBus
|
|
||||||
import info.nightscout.shared.interfaces.ResourceHelper
|
import info.nightscout.shared.interfaces.ResourceHelper
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
import info.nightscout.shared.utils.DateUtil
|
import info.nightscout.shared.utils.DateUtil
|
||||||
|
import info.nightscout.shared.utils.DateUtilImpl
|
||||||
import info.nightscout.sharedtests.TestBase
|
import info.nightscout.sharedtests.TestBase
|
||||||
import org.junit.jupiter.api.Assertions
|
import org.junit.jupiter.api.Assertions
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
|
@ -33,8 +33,7 @@ class CarbTimerImplTest : TestBase() {
|
||||||
@Mock lateinit var sp: SP
|
@Mock lateinit var sp: SP
|
||||||
@Mock lateinit var fabricPrivacy: FabricPrivacy
|
@Mock lateinit var fabricPrivacy: FabricPrivacy
|
||||||
@Mock lateinit var loop: Loop
|
@Mock lateinit var loop: Loop
|
||||||
@Mock lateinit var rxBus: RxBus
|
@Mock lateinit var constraintChecker: ConstraintsChecker
|
||||||
@Mock lateinit var constraintChecker: Constraints
|
|
||||||
@Mock lateinit var config: Config
|
@Mock lateinit var config: Config
|
||||||
@Mock lateinit var locationServiceHelper: LocationServiceHelper
|
@Mock lateinit var locationServiceHelper: LocationServiceHelper
|
||||||
@Mock lateinit var activePlugin: ActivePlugin
|
@Mock lateinit var activePlugin: ActivePlugin
|
||||||
|
@ -57,7 +56,7 @@ class CarbTimerImplTest : TestBase() {
|
||||||
fun init() {
|
fun init() {
|
||||||
Mockito.`when`(rh.gs(anyInt())).thenReturn("")
|
Mockito.`when`(rh.gs(anyInt())).thenReturn("")
|
||||||
Mockito.`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL)
|
Mockito.`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL)
|
||||||
dateUtil = DateUtil(context)
|
dateUtil = DateUtilImpl(context)
|
||||||
timerUtil = TimerUtil(context)
|
timerUtil = TimerUtil(context)
|
||||||
automationPlugin = AutomationPlugin(
|
automationPlugin = AutomationPlugin(
|
||||||
injector, rh, context, sp, fabricPrivacy, loop, rxBus, constraintChecker, aapsLogger, aapsSchedulers, config, locationServiceHelper, dateUtil,
|
injector, rh, context, sp, fabricPrivacy, loop, rxBus, constraintChecker, aapsLogger, aapsSchedulers, config, locationServiceHelper, dateUtil,
|
||||||
|
|
|
@ -9,7 +9,6 @@ import info.nightscout.automation.ui.TimerUtil
|
||||||
import info.nightscout.interfaces.Config
|
import info.nightscout.interfaces.Config
|
||||||
import info.nightscout.interfaces.pump.PumpEnactResult
|
import info.nightscout.interfaces.pump.PumpEnactResult
|
||||||
import info.nightscout.interfaces.queue.Callback
|
import info.nightscout.interfaces.queue.Callback
|
||||||
import info.nightscout.rx.bus.RxBus
|
|
||||||
import info.nightscout.shared.interfaces.ResourceHelper
|
import info.nightscout.shared.interfaces.ResourceHelper
|
||||||
import info.nightscout.shared.utils.DateUtil
|
import info.nightscout.shared.utils.DateUtil
|
||||||
import info.nightscout.sharedtests.TestBase
|
import info.nightscout.sharedtests.TestBase
|
||||||
|
@ -23,7 +22,6 @@ import org.mockito.Mockito.`when`
|
||||||
class ActionAlarmTest : TestBase() {
|
class ActionAlarmTest : TestBase() {
|
||||||
|
|
||||||
@Mock lateinit var rh: ResourceHelper
|
@Mock lateinit var rh: ResourceHelper
|
||||||
@Mock lateinit var rxBus: RxBus
|
|
||||||
@Mock lateinit var context: Context
|
@Mock lateinit var context: Context
|
||||||
@Mock lateinit var dateUtil: DateUtil
|
@Mock lateinit var dateUtil: DateUtil
|
||||||
@Mock lateinit var config: Config
|
@Mock lateinit var config: Config
|
||||||
|
|
|
@ -26,7 +26,7 @@ class ActionNotificationTest : TestBase() {
|
||||||
|
|
||||||
@Mock lateinit var rh: ResourceHelper
|
@Mock lateinit var rh: ResourceHelper
|
||||||
@Mock lateinit var context: Context
|
@Mock lateinit var context: Context
|
||||||
@Mock lateinit var rxBus: RxBus
|
@Mock lateinit var rxBusMocked: RxBus
|
||||||
@Mock lateinit var repository: AppRepository
|
@Mock lateinit var repository: AppRepository
|
||||||
|
|
||||||
private lateinit var sut: ActionNotification
|
private lateinit var sut: ActionNotification
|
||||||
|
@ -34,7 +34,7 @@ class ActionNotificationTest : TestBase() {
|
||||||
AndroidInjector {
|
AndroidInjector {
|
||||||
if (it is ActionNotification) {
|
if (it is ActionNotification) {
|
||||||
it.rh = rh
|
it.rh = rh
|
||||||
it.rxBus = rxBus
|
it.rxBus = rxBusMocked
|
||||||
it.repository = repository
|
it.repository = repository
|
||||||
}
|
}
|
||||||
if (it is PumpEnactResult) {
|
if (it is PumpEnactResult) {
|
||||||
|
@ -78,7 +78,7 @@ class ActionNotificationTest : TestBase() {
|
||||||
Assertions.assertTrue(result.success)
|
Assertions.assertTrue(result.success)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
Mockito.verify(rxBus, Mockito.times(2)).send(anyObject())
|
Mockito.verify(rxBusMocked, Mockito.times(2)).send(anyObject())
|
||||||
//Mockito.verify(repository, Mockito.times(1)).runTransaction(any(Transaction::class.java))
|
//Mockito.verify(repository, Mockito.times(1)).runTransaction(any(Transaction::class.java))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,29 +3,24 @@ package info.nightscout.automation.actions
|
||||||
import dagger.android.AndroidInjector
|
import dagger.android.AndroidInjector
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.automation.triggers.Trigger
|
import info.nightscout.automation.triggers.Trigger
|
||||||
import info.nightscout.database.entities.DeviceStatus
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.database.entities.OfflineEvent
|
import info.nightscout.database.entities.OfflineEvent
|
||||||
import info.nightscout.database.impl.AppRepository
|
import info.nightscout.database.impl.AppRepository
|
||||||
import info.nightscout.interfaces.ConfigBuilder
|
import info.nightscout.interfaces.ConfigBuilder
|
||||||
import info.nightscout.interfaces.GlucoseUnit
|
import info.nightscout.interfaces.GlucoseUnit
|
||||||
import info.nightscout.interfaces.aps.Loop
|
import info.nightscout.interfaces.aps.Loop
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.Constraint
|
||||||
import info.nightscout.interfaces.iob.IobCobCalculator
|
|
||||||
import info.nightscout.interfaces.logging.UserEntryLogger
|
import info.nightscout.interfaces.logging.UserEntryLogger
|
||||||
import info.nightscout.interfaces.plugin.PluginBase
|
import info.nightscout.interfaces.plugin.PluginBase
|
||||||
import info.nightscout.interfaces.plugin.PluginDescription
|
import info.nightscout.interfaces.plugin.PluginDescription
|
||||||
import info.nightscout.interfaces.plugin.PluginType
|
import info.nightscout.interfaces.plugin.PluginType
|
||||||
import info.nightscout.interfaces.profile.Profile
|
import info.nightscout.interfaces.profile.Profile
|
||||||
import info.nightscout.interfaces.profile.ProfileFunction
|
|
||||||
import info.nightscout.interfaces.profile.ProfileSource
|
import info.nightscout.interfaces.profile.ProfileSource
|
||||||
import info.nightscout.interfaces.pump.Pump
|
|
||||||
import info.nightscout.interfaces.pump.PumpEnactResult
|
import info.nightscout.interfaces.pump.PumpEnactResult
|
||||||
import info.nightscout.interfaces.queue.CommandQueue
|
import info.nightscout.interfaces.queue.CommandQueue
|
||||||
import info.nightscout.interfaces.receivers.ReceiverStatusStore
|
|
||||||
import info.nightscout.interfaces.smsCommunicator.SmsCommunicator
|
import info.nightscout.interfaces.smsCommunicator.SmsCommunicator
|
||||||
import info.nightscout.rx.logging.AAPSLogger
|
import info.nightscout.rx.logging.AAPSLogger
|
||||||
import info.nightscout.shared.interfaces.ResourceHelper
|
import info.nightscout.shared.interfaces.ResourceHelper
|
||||||
import info.nightscout.shared.utils.DateUtil
|
|
||||||
import info.nightscout.sharedtests.TestBaseWithProfile
|
import info.nightscout.sharedtests.TestBaseWithProfile
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
|
@ -45,7 +40,7 @@ ActionsTestBase : TestBaseWithProfile() {
|
||||||
|
|
||||||
private var suspended = false
|
private var suspended = false
|
||||||
override var lastRun: Loop.LastRun? = Loop.LastRun()
|
override var lastRun: Loop.LastRun? = Loop.LastRun()
|
||||||
override var closedLoopEnabled: Constraint<Boolean>? = Constraint(true)
|
override var closedLoopEnabled: Constraint<Boolean>? = ConstraintObject(true, injector)
|
||||||
override val isSuspended: Boolean = suspended
|
override val isSuspended: Boolean = suspended
|
||||||
override val isLGS: Boolean = false
|
override val isLGS: Boolean = false
|
||||||
override val isSuperBolus: Boolean = false
|
override val isSuperBolus: Boolean = false
|
||||||
|
@ -174,6 +169,9 @@ ActionsTestBase : TestBaseWithProfile() {
|
||||||
it.rh = rh
|
it.rh = rh
|
||||||
it.aapsLogger = aapsLogger
|
it.aapsLogger = aapsLogger
|
||||||
}
|
}
|
||||||
|
if (it is ConstraintObject<*>) {
|
||||||
|
it.aapsLogger = aapsLogger
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ import info.nightscout.database.impl.AppRepository
|
||||||
import info.nightscout.implementation.iob.GlucoseStatusProviderImpl
|
import info.nightscout.implementation.iob.GlucoseStatusProviderImpl
|
||||||
import info.nightscout.interfaces.aps.AutosensDataStore
|
import info.nightscout.interfaces.aps.AutosensDataStore
|
||||||
import info.nightscout.interfaces.receivers.ReceiverStatusStore
|
import info.nightscout.interfaces.receivers.ReceiverStatusStore
|
||||||
import info.nightscout.rx.bus.RxBus
|
|
||||||
import info.nightscout.sharedtests.TestBaseWithProfile
|
import info.nightscout.sharedtests.TestBaseWithProfile
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
|
@ -31,7 +30,7 @@ open class TriggerTestBase : TestBaseWithProfile() {
|
||||||
AndroidInjector {
|
AndroidInjector {
|
||||||
if (it is Trigger) {
|
if (it is Trigger) {
|
||||||
it.aapsLogger = aapsLogger
|
it.aapsLogger = aapsLogger
|
||||||
it.rxBus = RxBus(aapsSchedulers, aapsLogger)
|
it.rxBus = rxBus
|
||||||
it.rh = rh
|
it.rh = rh
|
||||||
it.profileFunction = profileFunction
|
it.profileFunction = profileFunction
|
||||||
it.sp = sp
|
it.sp = sp
|
||||||
|
|
|
@ -1,109 +1,135 @@
|
||||||
package info.nightscout.plugins.constraints
|
package info.nightscout.plugins.constraints
|
||||||
|
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.Constraint
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
|
import info.nightscout.interfaces.constraints.PluginConstraints
|
||||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||||
import info.nightscout.interfaces.profile.Profile
|
import info.nightscout.interfaces.profile.Profile
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class ConstraintsImpl @Inject constructor(private val activePlugin: ActivePlugin) : Constraints {
|
class ConstraintsCheckerImpl @Inject constructor(
|
||||||
|
private val activePlugin: ActivePlugin,
|
||||||
|
val injector: HasAndroidInjector
|
||||||
|
) : ConstraintsChecker {
|
||||||
|
|
||||||
|
override fun isLoopInvocationAllowed(): Constraint<Boolean> = isLoopInvocationAllowed(ConstraintObject(true, injector))
|
||||||
|
|
||||||
override fun isLoopInvocationAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isLoopInvocationAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)
|
||||||
for (p in constraintsPlugins) {
|
for (p in constraintsPlugins) {
|
||||||
val constraint = p as Constraints
|
val constraint = p as PluginConstraints
|
||||||
if (!p.isEnabled()) continue
|
if (!p.isEnabled()) continue
|
||||||
constraint.isLoopInvocationAllowed(value)
|
constraint.isLoopInvocationAllowed(value)
|
||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isClosedLoopAllowed(): Constraint<Boolean> = isClosedLoopAllowed(ConstraintObject(true, injector))
|
||||||
|
|
||||||
override fun isClosedLoopAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isClosedLoopAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)
|
||||||
for (p in constraintsPlugins) {
|
for (p in constraintsPlugins) {
|
||||||
val constraint = p as Constraints
|
val constraint = p as PluginConstraints
|
||||||
if (!p.isEnabled()) continue
|
if (!p.isEnabled()) continue
|
||||||
constraint.isClosedLoopAllowed(value)
|
constraint.isClosedLoopAllowed(value)
|
||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isLgsAllowed(): Constraint<Boolean> = isLgsAllowed(ConstraintObject(true, injector))
|
||||||
|
|
||||||
override fun isLgsAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isLgsAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)
|
||||||
for (p in constraintsPlugins) {
|
for (p in constraintsPlugins) {
|
||||||
val constraint = p as Constraints
|
val constraint = p as PluginConstraints
|
||||||
if (!p.isEnabled()) continue
|
if (!p.isEnabled()) continue
|
||||||
constraint.isLgsAllowed(value)
|
constraint.isLgsAllowed(value)
|
||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isAutosensModeEnabled(): Constraint<Boolean> = isAutosensModeEnabled(ConstraintObject(true, injector))
|
||||||
|
|
||||||
override fun isAutosensModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isAutosensModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)
|
||||||
for (p in constraintsPlugins) {
|
for (p in constraintsPlugins) {
|
||||||
val constraint = p as Constraints
|
val constraint = p as PluginConstraints
|
||||||
if (!p.isEnabled()) continue
|
if (!p.isEnabled()) continue
|
||||||
constraint.isAutosensModeEnabled(value)
|
constraint.isAutosensModeEnabled(value)
|
||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isSMBModeEnabled(): Constraint<Boolean> = isSMBModeEnabled(ConstraintObject(true, injector))
|
||||||
|
|
||||||
override fun isSMBModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isSMBModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)
|
||||||
for (p in constraintsPlugins) {
|
for (p in constraintsPlugins) {
|
||||||
val constraint = p as Constraints
|
val constraint = p as PluginConstraints
|
||||||
if (!p.isEnabled()) continue
|
if (!p.isEnabled()) continue
|
||||||
constraint.isSMBModeEnabled(value)
|
constraint.isSMBModeEnabled(value)
|
||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isDynIsfModeEnabled(): Constraint<Boolean> = isDynIsfModeEnabled(ConstraintObject(true, injector))
|
||||||
|
|
||||||
override fun isDynIsfModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isDynIsfModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)
|
||||||
for (p in constraintsPlugins) {
|
for (p in constraintsPlugins) {
|
||||||
val constraint = p as Constraints
|
val constraint = p as PluginConstraints
|
||||||
if (!p.isEnabled()) continue
|
if (!p.isEnabled()) continue
|
||||||
constraint.isDynIsfModeEnabled(value)
|
constraint.isDynIsfModeEnabled(value)
|
||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isUAMEnabled(): Constraint<Boolean> = isUAMEnabled(ConstraintObject(true, injector))
|
||||||
|
|
||||||
override fun isUAMEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isUAMEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)
|
||||||
for (p in constraintsPlugins) {
|
for (p in constraintsPlugins) {
|
||||||
val constraint = p as Constraints
|
val constraint = p as PluginConstraints
|
||||||
if (!p.isEnabled()) continue
|
if (!p.isEnabled()) continue
|
||||||
constraint.isUAMEnabled(value)
|
constraint.isUAMEnabled(value)
|
||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isAdvancedFilteringEnabled(): Constraint<Boolean> = isAdvancedFilteringEnabled(ConstraintObject(true, injector))
|
||||||
|
|
||||||
override fun isAdvancedFilteringEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isAdvancedFilteringEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)
|
||||||
for (p in constraintsPlugins) {
|
for (p in constraintsPlugins) {
|
||||||
val constraint = p as Constraints
|
val constraint = p as PluginConstraints
|
||||||
if (!p.isEnabled()) continue
|
if (!p.isEnabled()) continue
|
||||||
constraint.isAdvancedFilteringEnabled(value)
|
constraint.isAdvancedFilteringEnabled(value)
|
||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isSuperBolusEnabled(): Constraint<Boolean> = isSuperBolusEnabled(ConstraintObject(true, injector))
|
||||||
|
|
||||||
override fun isSuperBolusEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isSuperBolusEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)
|
||||||
for (p in constraintsPlugins) {
|
for (p in constraintsPlugins) {
|
||||||
val constraint = p as Constraints
|
val constraint = p as PluginConstraints
|
||||||
if (!p.isEnabled()) continue
|
if (!p.isEnabled()) continue
|
||||||
constraint.isSuperBolusEnabled(value)
|
constraint.isSuperBolusEnabled(value)
|
||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isAutomationEnabled(): Constraint<Boolean> = isAutomationEnabled(ConstraintObject(true, injector))
|
||||||
|
|
||||||
override fun applyBasalConstraints(absoluteRate: Constraint<Double>, profile: Profile): Constraint<Double> {
|
override fun applyBasalConstraints(absoluteRate: Constraint<Double>, profile: Profile): Constraint<Double> {
|
||||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)
|
||||||
for (p in constraintsPlugins) {
|
for (p in constraintsPlugins) {
|
||||||
val constraint = p as Constraints
|
val constraint = p as PluginConstraints
|
||||||
if (!p.isEnabled()) continue
|
if (!p.isEnabled()) continue
|
||||||
constraint.applyBasalConstraints(absoluteRate, profile)
|
constraint.applyBasalConstraints(absoluteRate, profile)
|
||||||
}
|
}
|
||||||
|
@ -111,9 +137,9 @@ class ConstraintsImpl @Inject constructor(private val activePlugin: ActivePlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun applyBasalPercentConstraints(percentRate: Constraint<Int>, profile: Profile): Constraint<Int> {
|
override fun applyBasalPercentConstraints(percentRate: Constraint<Int>, profile: Profile): Constraint<Int> {
|
||||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)
|
||||||
for (p in constraintsPlugins) {
|
for (p in constraintsPlugins) {
|
||||||
val constrain = p as Constraints
|
val constrain = p as PluginConstraints
|
||||||
if (!p.isEnabled()) continue
|
if (!p.isEnabled()) continue
|
||||||
constrain.applyBasalPercentConstraints(percentRate, profile)
|
constrain.applyBasalPercentConstraints(percentRate, profile)
|
||||||
}
|
}
|
||||||
|
@ -121,9 +147,9 @@ class ConstraintsImpl @Inject constructor(private val activePlugin: ActivePlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun applyBolusConstraints(insulin: Constraint<Double>): Constraint<Double> {
|
override fun applyBolusConstraints(insulin: Constraint<Double>): Constraint<Double> {
|
||||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)
|
||||||
for (p in constraintsPlugins) {
|
for (p in constraintsPlugins) {
|
||||||
val constrain = p as Constraints
|
val constrain = p as PluginConstraints
|
||||||
if (!p.isEnabled()) continue
|
if (!p.isEnabled()) continue
|
||||||
constrain.applyBolusConstraints(insulin)
|
constrain.applyBolusConstraints(insulin)
|
||||||
}
|
}
|
||||||
|
@ -131,9 +157,9 @@ class ConstraintsImpl @Inject constructor(private val activePlugin: ActivePlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun applyExtendedBolusConstraints(insulin: Constraint<Double>): Constraint<Double> {
|
override fun applyExtendedBolusConstraints(insulin: Constraint<Double>): Constraint<Double> {
|
||||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)
|
||||||
for (p in constraintsPlugins) {
|
for (p in constraintsPlugins) {
|
||||||
val constrain = p as Constraints
|
val constrain = p as PluginConstraints
|
||||||
if (!p.isEnabled()) continue
|
if (!p.isEnabled()) continue
|
||||||
constrain.applyExtendedBolusConstraints(insulin)
|
constrain.applyExtendedBolusConstraints(insulin)
|
||||||
}
|
}
|
||||||
|
@ -141,9 +167,9 @@ class ConstraintsImpl @Inject constructor(private val activePlugin: ActivePlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun applyCarbsConstraints(carbs: Constraint<Int>): Constraint<Int> {
|
override fun applyCarbsConstraints(carbs: Constraint<Int>): Constraint<Int> {
|
||||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)
|
||||||
for (p in constraintsPlugins) {
|
for (p in constraintsPlugins) {
|
||||||
val constrain = p as Constraints
|
val constrain = p as PluginConstraints
|
||||||
if (!p.isEnabled()) continue
|
if (!p.isEnabled()) continue
|
||||||
constrain.applyCarbsConstraints(carbs)
|
constrain.applyCarbsConstraints(carbs)
|
||||||
}
|
}
|
||||||
|
@ -151,9 +177,9 @@ class ConstraintsImpl @Inject constructor(private val activePlugin: ActivePlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> {
|
override fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> {
|
||||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)
|
||||||
for (p in constraintsPlugins) {
|
for (p in constraintsPlugins) {
|
||||||
val constrain = p as Constraints
|
val constrain = p as PluginConstraints
|
||||||
if (!p.isEnabled()) continue
|
if (!p.isEnabled()) continue
|
||||||
constrain.applyMaxIOBConstraints(maxIob)
|
constrain.applyMaxIOBConstraints(maxIob)
|
||||||
}
|
}
|
||||||
|
@ -161,12 +187,34 @@ class ConstraintsImpl @Inject constructor(private val activePlugin: ActivePlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isAutomationEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isAutomationEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)
|
||||||
for (p in constraintsPlugins) {
|
for (p in constraintsPlugins) {
|
||||||
val constraint = p as Constraints
|
val constraint = p as PluginConstraints
|
||||||
if (!p.isEnabled()) continue
|
if (!p.isEnabled()) continue
|
||||||
constraint.isAutomationEnabled(value)
|
constraint.isAutomationEnabled(value)
|
||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine max values by walking through all constraints
|
||||||
|
*/
|
||||||
|
|
||||||
|
override fun getMaxBasalAllowed(profile: Profile): Constraint<Double> =
|
||||||
|
applyBasalConstraints(ConstraintObject(Double.MAX_VALUE, injector), profile)
|
||||||
|
|
||||||
|
override fun getMaxBasalPercentAllowed(profile: Profile): Constraint<Int> =
|
||||||
|
applyBasalPercentConstraints(ConstraintObject(Int.MAX_VALUE, injector), profile)
|
||||||
|
|
||||||
|
override fun getMaxBolusAllowed(): Constraint<Double> =
|
||||||
|
applyBolusConstraints(ConstraintObject(Double.MAX_VALUE, injector))
|
||||||
|
|
||||||
|
override fun getMaxExtendedBolusAllowed(): Constraint<Double> =
|
||||||
|
applyExtendedBolusConstraints(ConstraintObject(Double.MAX_VALUE, injector))
|
||||||
|
|
||||||
|
override fun getMaxCarbsAllowed(): Constraint<Int> =
|
||||||
|
applyCarbsConstraints(ConstraintObject(Int.MAX_VALUE, injector))
|
||||||
|
|
||||||
|
override fun getMaxIOBAllowed(): Constraint<Double> =
|
||||||
|
applyMaxIOBConstraints(ConstraintObject(Double.MAX_VALUE, injector))
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@ import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||||
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
|
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.Constraint
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.PluginConstraints
|
||||||
import info.nightscout.interfaces.iob.IobCobCalculator
|
import info.nightscout.interfaces.iob.IobCobCalculator
|
||||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||||
import info.nightscout.interfaces.plugin.PluginBase
|
import info.nightscout.interfaces.plugin.PluginBase
|
||||||
|
@ -48,7 +48,7 @@ class BgQualityCheckPlugin @Inject constructor(
|
||||||
.showInList(false)
|
.showInList(false)
|
||||||
.pluginName(R.string.bg_quality),
|
.pluginName(R.string.bg_quality),
|
||||||
aapsLogger, rh, injector
|
aapsLogger, rh, injector
|
||||||
), Constraints, BgQualityCheck {
|
), PluginConstraints, BgQualityCheck {
|
||||||
|
|
||||||
private var disposable: CompositeDisposable = CompositeDisposable()
|
private var disposable: CompositeDisposable = CompositeDisposable()
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ class BgQualityCheckPlugin @Inject constructor(
|
||||||
// Fallback to LGS if BG values are doubled
|
// Fallback to LGS if BG values are doubled
|
||||||
override fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> =
|
override fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> =
|
||||||
if (state == BgQualityCheck.State.DOUBLED)
|
if (state == BgQualityCheck.State.DOUBLED)
|
||||||
maxIob.set(aapsLogger, 0.0, "Doubled values in BGSource", this)
|
maxIob.set(0.0, "Doubled values in BGSource", this)
|
||||||
else
|
else
|
||||||
maxIob
|
maxIob
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,9 @@ package info.nightscout.plugins.constraints.di
|
||||||
import dagger.Binds
|
import dagger.Binds
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
|
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.versionChecker.VersionCheckerUtils
|
import info.nightscout.interfaces.versionChecker.VersionCheckerUtils
|
||||||
import info.nightscout.plugins.constraints.ConstraintsImpl
|
import info.nightscout.plugins.constraints.ConstraintsCheckerImpl
|
||||||
import info.nightscout.plugins.constraints.bgQualityCheck.BgQualityCheckPlugin
|
import info.nightscout.plugins.constraints.bgQualityCheck.BgQualityCheckPlugin
|
||||||
import info.nightscout.plugins.constraints.versionChecker.VersionCheckerUtilsImpl
|
import info.nightscout.plugins.constraints.versionChecker.VersionCheckerUtilsImpl
|
||||||
|
|
||||||
|
@ -24,6 +24,6 @@ abstract class PluginsConstraintsModule {
|
||||||
|
|
||||||
@Binds fun bindVersionCheckerUtils(versionCheckerUtils: VersionCheckerUtilsImpl): VersionCheckerUtils
|
@Binds fun bindVersionCheckerUtils(versionCheckerUtils: VersionCheckerUtilsImpl): VersionCheckerUtils
|
||||||
@Binds fun bindBgQualityCheck(bgQualityCheck: BgQualityCheckPlugin): BgQualityCheck
|
@Binds fun bindBgQualityCheck(bgQualityCheck: BgQualityCheckPlugin): BgQualityCheck
|
||||||
@Binds fun bindsConstraints(constraintsImpl: ConstraintsImpl): Constraints
|
@Binds fun bindsConstraintChecker(constraintsCheckerImpl: ConstraintsCheckerImpl): ConstraintsChecker
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@ package info.nightscout.plugins.constraints.dstHelper
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.interfaces.aps.Loop
|
import info.nightscout.interfaces.aps.Loop
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.Constraint
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.PluginConstraints
|
||||||
import info.nightscout.interfaces.notifications.Notification
|
import info.nightscout.interfaces.notifications.Notification
|
||||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||||
import info.nightscout.interfaces.plugin.PluginBase
|
import info.nightscout.interfaces.plugin.PluginBase
|
||||||
|
@ -35,7 +35,7 @@ class DstHelperPlugin @Inject constructor(
|
||||||
.showInList(false)
|
.showInList(false)
|
||||||
.pluginName(R.string.dst_plugin_name),
|
.pluginName(R.string.dst_plugin_name),
|
||||||
aapsLogger, rh, injector
|
aapsLogger, rh, injector
|
||||||
), Constraints {
|
), PluginConstraints {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ class DstHelperPlugin @Inject constructor(
|
||||||
} else {
|
} else {
|
||||||
aapsLogger.debug(LTag.CONSTRAINTS, "Loop already suspended")
|
aapsLogger.debug(LTag.CONSTRAINTS, "Loop already suspended")
|
||||||
}
|
}
|
||||||
value.set(aapsLogger, false, "DST in last 3 hours.", this)
|
value.set(false, "DST in last 3 hours.", this)
|
||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package info.nightscout.plugins.constraints.objectives
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.interfaces.Config
|
import info.nightscout.interfaces.Config
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.Constraint
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
|
||||||
import info.nightscout.interfaces.constraints.Objectives
|
import info.nightscout.interfaces.constraints.Objectives
|
||||||
import info.nightscout.interfaces.constraints.Objectives.Companion.AUTOSENS_OBJECTIVE
|
import info.nightscout.interfaces.constraints.Objectives.Companion.AUTOSENS_OBJECTIVE
|
||||||
import info.nightscout.interfaces.constraints.Objectives.Companion.AUTO_OBJECTIVE
|
import info.nightscout.interfaces.constraints.Objectives.Companion.AUTO_OBJECTIVE
|
||||||
|
@ -12,6 +11,7 @@ import info.nightscout.interfaces.constraints.Objectives.Companion.FIRST_OBJECTI
|
||||||
import info.nightscout.interfaces.constraints.Objectives.Companion.MAXBASAL_OBJECTIVE
|
import info.nightscout.interfaces.constraints.Objectives.Companion.MAXBASAL_OBJECTIVE
|
||||||
import info.nightscout.interfaces.constraints.Objectives.Companion.MAXIOB_ZERO_CL_OBJECTIVE
|
import info.nightscout.interfaces.constraints.Objectives.Companion.MAXIOB_ZERO_CL_OBJECTIVE
|
||||||
import info.nightscout.interfaces.constraints.Objectives.Companion.SMB_OBJECTIVE
|
import info.nightscout.interfaces.constraints.Objectives.Companion.SMB_OBJECTIVE
|
||||||
|
import info.nightscout.interfaces.constraints.PluginConstraints
|
||||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||||
import info.nightscout.interfaces.plugin.PluginBase
|
import info.nightscout.interfaces.plugin.PluginBase
|
||||||
import info.nightscout.interfaces.plugin.PluginDescription
|
import info.nightscout.interfaces.plugin.PluginDescription
|
||||||
|
@ -54,7 +54,7 @@ class ObjectivesPlugin @Inject constructor(
|
||||||
.shortName(R.string.objectives_shortname)
|
.shortName(R.string.objectives_shortname)
|
||||||
.description(R.string.description_objectives),
|
.description(R.string.description_objectives),
|
||||||
aapsLogger, rh, injector
|
aapsLogger, rh, injector
|
||||||
), Constraints, Objectives {
|
), PluginConstraints, Objectives {
|
||||||
|
|
||||||
var objectives: MutableList<Objective> = ArrayList()
|
var objectives: MutableList<Objective> = ArrayList()
|
||||||
|
|
||||||
|
@ -112,49 +112,49 @@ class ObjectivesPlugin @Inject constructor(
|
||||||
*/
|
*/
|
||||||
override fun isLoopInvocationAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isLoopInvocationAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
if (!objectives[FIRST_OBJECTIVE].isStarted)
|
if (!objectives[FIRST_OBJECTIVE].isStarted)
|
||||||
value.set(aapsLogger, false, rh.gs(R.string.objectivenotstarted, FIRST_OBJECTIVE + 1), this)
|
value.set(false, rh.gs(R.string.objectivenotstarted, FIRST_OBJECTIVE + 1), this)
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isLgsAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isLgsAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
if (!objectives[MAXBASAL_OBJECTIVE].isStarted)
|
if (!objectives[MAXBASAL_OBJECTIVE].isStarted)
|
||||||
value.set(aapsLogger, false, rh.gs(R.string.objectivenotstarted, MAXBASAL_OBJECTIVE + 1), this)
|
value.set(false, rh.gs(R.string.objectivenotstarted, MAXBASAL_OBJECTIVE + 1), this)
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isClosedLoopAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isClosedLoopAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
if (!objectives[MAXIOB_ZERO_CL_OBJECTIVE].isStarted)
|
if (!objectives[MAXIOB_ZERO_CL_OBJECTIVE].isStarted)
|
||||||
value.set(aapsLogger, false, rh.gs(R.string.objectivenotstarted, MAXIOB_ZERO_CL_OBJECTIVE + 1), this)
|
value.set(false, rh.gs(R.string.objectivenotstarted, MAXIOB_ZERO_CL_OBJECTIVE + 1), this)
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isAutosensModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isAutosensModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
if (!objectives[AUTOSENS_OBJECTIVE].isStarted)
|
if (!objectives[AUTOSENS_OBJECTIVE].isStarted)
|
||||||
value.set(aapsLogger, false, rh.gs(R.string.objectivenotstarted, AUTOSENS_OBJECTIVE + 1), this)
|
value.set(false, rh.gs(R.string.objectivenotstarted, AUTOSENS_OBJECTIVE + 1), this)
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isSMBModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isSMBModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
if (!objectives[SMB_OBJECTIVE].isStarted)
|
if (!objectives[SMB_OBJECTIVE].isStarted)
|
||||||
value.set(aapsLogger, false, rh.gs(R.string.objectivenotstarted, SMB_OBJECTIVE + 1), this)
|
value.set(false, rh.gs(R.string.objectivenotstarted, SMB_OBJECTIVE + 1), this)
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isDynIsfModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isDynIsfModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
if (!objectives[DYN_ISF_OBJECTIVE].isStarted)
|
if (!objectives[DYN_ISF_OBJECTIVE].isStarted)
|
||||||
value.set(aapsLogger, false, rh.gs(R.string.objectivenotstarted, DYN_ISF_OBJECTIVE + 1), this)
|
value.set(false, rh.gs(R.string.objectivenotstarted, DYN_ISF_OBJECTIVE + 1), this)
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> {
|
override fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> {
|
||||||
if (objectives[MAXIOB_ZERO_CL_OBJECTIVE].isStarted && !objectives[MAXIOB_ZERO_CL_OBJECTIVE].isAccomplished)
|
if (objectives[MAXIOB_ZERO_CL_OBJECTIVE].isStarted && !objectives[MAXIOB_ZERO_CL_OBJECTIVE].isAccomplished)
|
||||||
maxIob.set(aapsLogger, 0.0, rh.gs(R.string.objectivenotfinished, MAXIOB_ZERO_CL_OBJECTIVE + 1), this)
|
maxIob.set(0.0, rh.gs(R.string.objectivenotfinished, MAXIOB_ZERO_CL_OBJECTIVE + 1), this)
|
||||||
return maxIob
|
return maxIob
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isAutomationEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isAutomationEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
if (!objectives[AUTO_OBJECTIVE].isStarted)
|
if (!objectives[AUTO_OBJECTIVE].isStarted)
|
||||||
value.set(aapsLogger, false, rh.gs(R.string.objectivenotstarted, AUTO_OBJECTIVE + 1), this)
|
value.set(false, rh.gs(R.string.objectivenotstarted, AUTO_OBJECTIVE + 1), this)
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
package info.nightscout.plugins.constraints.objectives.objectives
|
package info.nightscout.plugins.constraints.objectives.objectives
|
||||||
|
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.interfaces.Constants
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.PluginConstraints
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
|
||||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||||
import info.nightscout.interfaces.profile.ProfileFunction
|
import info.nightscout.interfaces.profile.ProfileFunction
|
||||||
import info.nightscout.plugins.constraints.R
|
import info.nightscout.plugins.constraints.R
|
||||||
|
@ -14,12 +13,13 @@ class Objective4(injector: HasAndroidInjector) : Objective(injector, "maxbasal",
|
||||||
|
|
||||||
@Inject lateinit var profileFunction: ProfileFunction
|
@Inject lateinit var profileFunction: ProfileFunction
|
||||||
@Inject lateinit var activePlugin: ActivePlugin
|
@Inject lateinit var activePlugin: ActivePlugin
|
||||||
|
|
||||||
init {
|
init {
|
||||||
tasks.add(
|
tasks.add(
|
||||||
object : Task(this, R.string.objectives_maxbasal_gate) {
|
object : Task(this, R.string.objectives_maxbasal_gate) {
|
||||||
override fun isCompleted(): Boolean {
|
override fun isCompleted(): Boolean {
|
||||||
val profile = profileFunction.getProfile() ?: return false
|
val profile = profileFunction.getProfile() ?: return false
|
||||||
val maxBasalSet = (activePlugin.activeAPS as Constraints).applyBasalConstraints(Constraint(Constants.REALLYHIGHBASALRATE), profile)
|
val maxBasalSet = (activePlugin.activeAPS as PluginConstraints).applyBasalConstraints(ConstraintObject(Double.MAX_VALUE, injector), profile)
|
||||||
val maxDailyBasal = profile.getMaxDailyBasal()
|
val maxDailyBasal = profile.getMaxDailyBasal()
|
||||||
return maxBasalSet.value() > 2.8 * maxDailyBasal
|
return maxBasalSet.value() > 2.8 * maxDailyBasal
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package info.nightscout.plugins.constraints.objectives.objectives
|
package info.nightscout.plugins.constraints.objectives.objectives
|
||||||
|
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.plugins.constraints.R
|
import info.nightscout.plugins.constraints.R
|
||||||
import info.nightscout.plugins.constraints.safety.SafetyPlugin
|
import info.nightscout.plugins.constraints.safety.SafetyPlugin
|
||||||
import info.nightscout.shared.utils.T
|
import info.nightscout.shared.utils.T
|
||||||
|
@ -17,7 +17,7 @@ class Objective5(injector: HasAndroidInjector) : Objective(injector, "maxiobzero
|
||||||
tasks.add(
|
tasks.add(
|
||||||
object : Task(this, R.string.closedmodeenabled) {
|
object : Task(this, R.string.closedmodeenabled) {
|
||||||
override fun isCompleted(): Boolean {
|
override fun isCompleted(): Boolean {
|
||||||
val closedLoopEnabled = Constraint(true)
|
val closedLoopEnabled = ConstraintObject(true, injector)
|
||||||
safetyPlugin.isClosedLoopAllowed(closedLoopEnabled)
|
safetyPlugin.isClosedLoopAllowed(closedLoopEnabled)
|
||||||
return closedLoopEnabled.value()
|
return closedLoopEnabled.value()
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package info.nightscout.plugins.constraints.objectives.objectives
|
||||||
|
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.interfaces.ApsMode
|
import info.nightscout.interfaces.ApsMode
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.plugins.constraints.R
|
import info.nightscout.plugins.constraints.R
|
||||||
import info.nightscout.shared.utils.T
|
import info.nightscout.shared.utils.T
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -10,7 +10,7 @@ import javax.inject.Inject
|
||||||
@Suppress("SpellCheckingInspection")
|
@Suppress("SpellCheckingInspection")
|
||||||
class Objective6(injector: HasAndroidInjector) : Objective(injector, "maxiob", R.string.objectives_maxiob_objective, R.string.objectives_maxiob_gate) {
|
class Objective6(injector: HasAndroidInjector) : Objective(injector, "maxiob", R.string.objectives_maxiob_objective, R.string.objectives_maxiob_gate) {
|
||||||
|
|
||||||
@Inject lateinit var constraintChecker: Constraints
|
@Inject lateinit var constraintChecker: ConstraintsChecker
|
||||||
|
|
||||||
init {
|
init {
|
||||||
tasks.add(MinimumDurationTask(this, T.days(1).msecs()))
|
tasks.add(MinimumDurationTask(this, T.days(1).msecs()))
|
||||||
|
|
|
@ -4,7 +4,7 @@ import android.content.Context
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import com.scottyab.rootbeer.RootBeer
|
import com.scottyab.rootbeer.RootBeer
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.PluginConstraints
|
||||||
import info.nightscout.interfaces.plugin.PluginBase
|
import info.nightscout.interfaces.plugin.PluginBase
|
||||||
import info.nightscout.interfaces.plugin.PluginDescription
|
import info.nightscout.interfaces.plugin.PluginDescription
|
||||||
import info.nightscout.interfaces.plugin.PluginType
|
import info.nightscout.interfaces.plugin.PluginType
|
||||||
|
@ -28,7 +28,7 @@ class PhoneCheckerPlugin @Inject constructor(
|
||||||
.showInList(false)
|
.showInList(false)
|
||||||
.pluginName(R.string.phone_checker),
|
.pluginName(R.string.phone_checker),
|
||||||
aapsLogger, rh, injector
|
aapsLogger, rh, injector
|
||||||
), Constraints {
|
), PluginConstraints {
|
||||||
|
|
||||||
var phoneRooted: Boolean = false
|
var phoneRooted: Boolean = false
|
||||||
var devMode: Boolean = false
|
var devMode: Boolean = false
|
||||||
|
@ -36,8 +36,10 @@ class PhoneCheckerPlugin @Inject constructor(
|
||||||
val manufacturer: String = Build.MANUFACTURER
|
val manufacturer: String = Build.MANUFACTURER
|
||||||
|
|
||||||
private fun isDevModeEnabled(): Boolean {
|
private fun isDevModeEnabled(): Boolean {
|
||||||
return android.provider.Settings.Secure.getInt(context.contentResolver,
|
return android.provider.Settings.Secure.getInt(
|
||||||
android.provider.Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0
|
context.contentResolver,
|
||||||
|
android.provider.Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0
|
||||||
|
) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package info.nightscout.plugins.constraints.safety
|
package info.nightscout.plugins.constraints.safety
|
||||||
|
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.core.utils.extensions.putDouble
|
import info.nightscout.core.utils.extensions.putDouble
|
||||||
import info.nightscout.core.utils.extensions.putInt
|
import info.nightscout.core.utils.extensions.putInt
|
||||||
import info.nightscout.core.utils.extensions.putString
|
import info.nightscout.core.utils.extensions.putString
|
||||||
|
@ -10,7 +11,8 @@ import info.nightscout.core.utils.extensions.storeString
|
||||||
import info.nightscout.interfaces.ApsMode
|
import info.nightscout.interfaces.ApsMode
|
||||||
import info.nightscout.interfaces.Config
|
import info.nightscout.interfaces.Config
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.Constraint
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
|
import info.nightscout.interfaces.constraints.PluginConstraints
|
||||||
import info.nightscout.interfaces.constraints.Safety
|
import info.nightscout.interfaces.constraints.Safety
|
||||||
import info.nightscout.interfaces.iob.IobCobCalculator
|
import info.nightscout.interfaces.iob.IobCobCalculator
|
||||||
import info.nightscout.interfaces.notifications.Notification
|
import info.nightscout.interfaces.notifications.Notification
|
||||||
|
@ -39,7 +41,7 @@ class SafetyPlugin @Inject constructor(
|
||||||
aapsLogger: AAPSLogger,
|
aapsLogger: AAPSLogger,
|
||||||
rh: ResourceHelper,
|
rh: ResourceHelper,
|
||||||
private val sp: SP,
|
private val sp: SP,
|
||||||
private val constraintChecker: Constraints,
|
private val constraintChecker: ConstraintsChecker,
|
||||||
private val activePlugin: ActivePlugin,
|
private val activePlugin: ActivePlugin,
|
||||||
private val hardLimits: HardLimits,
|
private val hardLimits: HardLimits,
|
||||||
private val config: Config,
|
private val config: Config,
|
||||||
|
@ -56,57 +58,57 @@ class SafetyPlugin @Inject constructor(
|
||||||
.pluginName(R.string.safety)
|
.pluginName(R.string.safety)
|
||||||
.preferencesId(R.xml.pref_safety),
|
.preferencesId(R.xml.pref_safety),
|
||||||
aapsLogger, rh, injector
|
aapsLogger, rh, injector
|
||||||
), Constraints, Safety {
|
), PluginConstraints, Safety {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constraints interface
|
* Constraints interface
|
||||||
*/
|
*/
|
||||||
override fun isLoopInvocationAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isLoopInvocationAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
if (!activePlugin.activePump.pumpDescription.isTempBasalCapable) value.set(aapsLogger, false, rh.gs(R.string.pumpisnottempbasalcapable), this)
|
if (!activePlugin.activePump.pumpDescription.isTempBasalCapable) value.set(false, rh.gs(R.string.pumpisnottempbasalcapable), this)
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isClosedLoopAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isClosedLoopAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
val mode = ApsMode.fromString(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name))
|
val mode = ApsMode.fromString(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name))
|
||||||
if (mode == ApsMode.OPEN) value.set(aapsLogger, false, rh.gs(R.string.closedmodedisabledinpreferences), this)
|
if (mode == ApsMode.OPEN) value.set(false, rh.gs(R.string.closedmodedisabledinpreferences), this)
|
||||||
if (!config.isEngineeringModeOrRelease()) {
|
if (!config.isEngineeringModeOrRelease()) {
|
||||||
if (value.value()) {
|
if (value.value()) {
|
||||||
uiInteraction.addNotification(Notification.TOAST_ALARM, rh.gs(R.string.closed_loop_disabled_on_dev_branch), Notification.NORMAL)
|
uiInteraction.addNotification(Notification.TOAST_ALARM, rh.gs(R.string.closed_loop_disabled_on_dev_branch), Notification.NORMAL)
|
||||||
}
|
}
|
||||||
value.set(aapsLogger, false, rh.gs(R.string.closed_loop_disabled_on_dev_branch), this)
|
value.set(false, rh.gs(R.string.closed_loop_disabled_on_dev_branch), this)
|
||||||
}
|
}
|
||||||
val pump = activePlugin.activePump
|
val pump = activePlugin.activePump
|
||||||
if (!pump.isFakingTempsByExtendedBoluses && iobCobCalculator.getExtendedBolus(dateUtil.now()) != null) {
|
if (!pump.isFakingTempsByExtendedBoluses && iobCobCalculator.getExtendedBolus(dateUtil.now()) != null) {
|
||||||
value.set(aapsLogger, false, rh.gs(R.string.closed_loop_disabled_with_eb), this)
|
value.set(false, rh.gs(R.string.closed_loop_disabled_with_eb), this)
|
||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isSMBModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isSMBModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
val closedLoop = constraintChecker.isClosedLoopAllowed()
|
val closedLoop = constraintChecker.isClosedLoopAllowed()
|
||||||
if (!closedLoop.value()) value.set(aapsLogger, false, rh.gs(R.string.smbnotallowedinopenloopmode), this)
|
if (!closedLoop.value()) value.set(false, rh.gs(R.string.smbnotallowedinopenloopmode), this)
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isAdvancedFilteringEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isAdvancedFilteringEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
val bgSource = activePlugin.activeBgSource
|
val bgSource = activePlugin.activeBgSource
|
||||||
if (!bgSource.advancedFilteringSupported()) value.set(aapsLogger, false, rh.gs(R.string.smbalwaysdisabled), this)
|
if (!bgSource.advancedFilteringSupported()) value.set(false, rh.gs(R.string.smbalwaysdisabled), this)
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun applyBasalConstraints(absoluteRate: Constraint<Double>, profile: Profile): Constraint<Double> {
|
override fun applyBasalConstraints(absoluteRate: Constraint<Double>, profile: Profile): Constraint<Double> {
|
||||||
absoluteRate.setIfGreater(aapsLogger, 0.0, rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, 0.0, rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), this)
|
absoluteRate.setIfGreater(0.0, rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, 0.0, rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), this)
|
||||||
absoluteRate.setIfSmaller(aapsLogger, hardLimits.maxBasal(), rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, hardLimits.maxBasal(), rh.gs(R.string.hardlimit)), this)
|
absoluteRate.setIfSmaller(hardLimits.maxBasal(), rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, hardLimits.maxBasal(), rh.gs(R.string.hardlimit)), this)
|
||||||
val pump = activePlugin.activePump
|
val pump = activePlugin.activePump
|
||||||
// check for pump max
|
// check for pump max
|
||||||
if (pump.pumpDescription.tempBasalStyle == PumpDescription.ABSOLUTE) {
|
if (pump.pumpDescription.tempBasalStyle == PumpDescription.ABSOLUTE) {
|
||||||
val pumpLimit = pump.pumpDescription.pumpType.tbrSettings?.maxDose ?: 0.0
|
val pumpLimit = pump.pumpDescription.pumpType.tbrSettings?.maxDose ?: 0.0
|
||||||
absoluteRate.setIfSmaller(aapsLogger, pumpLimit, rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, pumpLimit, rh.gs(info.nightscout.core.ui.R.string.pumplimit)), this)
|
absoluteRate.setIfSmaller(pumpLimit, rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, pumpLimit, rh.gs(info.nightscout.core.ui.R.string.pumplimit)), this)
|
||||||
}
|
}
|
||||||
|
|
||||||
// do rounding
|
// do rounding
|
||||||
if (pump.pumpDescription.tempBasalStyle == PumpDescription.ABSOLUTE) {
|
if (pump.pumpDescription.tempBasalStyle == PumpDescription.ABSOLUTE) {
|
||||||
absoluteRate.set(aapsLogger, Round.roundTo(absoluteRate.value(), pump.pumpDescription.tempAbsoluteStep))
|
absoluteRate.set(Round.roundTo(absoluteRate.value(), pump.pumpDescription.tempAbsoluteStep))
|
||||||
}
|
}
|
||||||
return absoluteRate
|
return absoluteRate
|
||||||
}
|
}
|
||||||
|
@ -119,52 +121,58 @@ class SafetyPlugin @Inject constructor(
|
||||||
currentBasal
|
currentBasal
|
||||||
) + " U/h", this
|
) + " U/h", this
|
||||||
)
|
)
|
||||||
val absoluteConstraint = Constraint(absoluteRate)
|
val absoluteConstraint = ConstraintObject(absoluteRate, injector)
|
||||||
applyBasalConstraints(absoluteConstraint, profile)
|
applyBasalConstraints(absoluteConstraint, profile)
|
||||||
percentRate.copyReasons(absoluteConstraint)
|
percentRate.copyReasons(absoluteConstraint)
|
||||||
val pump = activePlugin.activePump
|
val pump = activePlugin.activePump
|
||||||
var percentRateAfterConst = java.lang.Double.valueOf(absoluteConstraint.value() / currentBasal * 100).toInt()
|
var percentRateAfterConst = java.lang.Double.valueOf(absoluteConstraint.value() / currentBasal * 100).toInt()
|
||||||
percentRateAfterConst = if (percentRateAfterConst < 100) Round.ceilTo(percentRateAfterConst.toDouble(), pump.pumpDescription.tempPercentStep.toDouble()).toInt() else Round.floorTo(percentRateAfterConst.toDouble(), pump.pumpDescription.tempPercentStep.toDouble()).toInt()
|
percentRateAfterConst =
|
||||||
percentRate.set(aapsLogger, percentRateAfterConst, rh.gs(info.nightscout.core.ui.R.string.limitingpercentrate, percentRateAfterConst, rh.gs(info.nightscout.core.ui.R.string.pumplimit)), this)
|
if (percentRateAfterConst < 100) Round.ceilTo(percentRateAfterConst.toDouble(), pump.pumpDescription.tempPercentStep.toDouble())
|
||||||
|
.toInt() else Round.floorTo(percentRateAfterConst.toDouble(), pump.pumpDescription.tempPercentStep.toDouble()).toInt()
|
||||||
|
percentRate.set(percentRateAfterConst, rh.gs(info.nightscout.core.ui.R.string.limitingpercentrate, percentRateAfterConst, rh.gs(info.nightscout.core.ui.R.string.pumplimit)), this)
|
||||||
if (pump.pumpDescription.tempBasalStyle == PumpDescription.PERCENT) {
|
if (pump.pumpDescription.tempBasalStyle == PumpDescription.PERCENT) {
|
||||||
val pumpLimit = pump.pumpDescription.pumpType.tbrSettings?.maxDose ?: 0.0
|
val pumpLimit = pump.pumpDescription.pumpType.tbrSettings?.maxDose ?: 0.0
|
||||||
percentRate.setIfSmaller(aapsLogger, pumpLimit.toInt(), rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, pumpLimit, rh.gs(info.nightscout.core.ui.R.string.pumplimit)), this)
|
percentRate.setIfSmaller(pumpLimit.toInt(), rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, pumpLimit, rh.gs(info.nightscout.core.ui.R.string.pumplimit)), this)
|
||||||
}
|
}
|
||||||
return percentRate
|
return percentRate
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun applyBolusConstraints(insulin: Constraint<Double>): Constraint<Double> {
|
override fun applyBolusConstraints(insulin: Constraint<Double>): Constraint<Double> {
|
||||||
insulin.setIfGreater(aapsLogger, 0.0, rh.gs(info.nightscout.core.ui.R.string.limitingbolus, 0.0, rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), this)
|
insulin.setIfGreater(0.0, rh.gs(info.nightscout.core.ui.R.string.limitingbolus, 0.0, rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), this)
|
||||||
val maxBolus = sp.getDouble(info.nightscout.core.utils.R.string.key_treatmentssafety_maxbolus, 3.0)
|
val maxBolus = sp.getDouble(info.nightscout.core.utils.R.string.key_treatmentssafety_maxbolus, 3.0)
|
||||||
insulin.setIfSmaller(aapsLogger, maxBolus, rh.gs(info.nightscout.core.ui.R.string.limitingbolus, maxBolus, rh.gs(R.string.maxvalueinpreferences)), this)
|
insulin.setIfSmaller(maxBolus, rh.gs(info.nightscout.core.ui.R.string.limitingbolus, maxBolus, rh.gs(R.string.maxvalueinpreferences)), this)
|
||||||
insulin.setIfSmaller(aapsLogger, hardLimits.maxBolus(), rh.gs(info.nightscout.core.ui.R.string.limitingbolus, hardLimits.maxBolus(), rh.gs(R.string.hardlimit)), this)
|
insulin.setIfSmaller(hardLimits.maxBolus(), rh.gs(info.nightscout.core.ui.R.string.limitingbolus, hardLimits.maxBolus(), rh.gs(R.string.hardlimit)), this)
|
||||||
val pump = activePlugin.activePump
|
val pump = activePlugin.activePump
|
||||||
val rounded = pump.pumpDescription.pumpType.determineCorrectBolusSize(insulin.value())
|
val rounded = pump.pumpDescription.pumpType.determineCorrectBolusSize(insulin.value())
|
||||||
insulin.setIfDifferent(aapsLogger, rounded, rh.gs(info.nightscout.core.ui.R.string.pumplimit), this)
|
insulin.setIfDifferent(rounded, rh.gs(info.nightscout.core.ui.R.string.pumplimit), this)
|
||||||
return insulin
|
return insulin
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun applyExtendedBolusConstraints(insulin: Constraint<Double>): Constraint<Double> {
|
override fun applyExtendedBolusConstraints(insulin: Constraint<Double>): Constraint<Double> {
|
||||||
insulin.setIfGreater(aapsLogger, 0.0, rh.gs(R.string.limitingextendedbolus, 0.0, rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), this)
|
insulin.setIfGreater(0.0, rh.gs(R.string.limitingextendedbolus, 0.0, rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), this)
|
||||||
val maxBolus = sp.getDouble(info.nightscout.core.utils.R.string.key_treatmentssafety_maxbolus, 3.0)
|
val maxBolus = sp.getDouble(info.nightscout.core.utils.R.string.key_treatmentssafety_maxbolus, 3.0)
|
||||||
insulin.setIfSmaller(aapsLogger, maxBolus, rh.gs(R.string.limitingextendedbolus, maxBolus, rh.gs(R.string.maxvalueinpreferences)), this)
|
insulin.setIfSmaller(maxBolus, rh.gs(R.string.limitingextendedbolus, maxBolus, rh.gs(R.string.maxvalueinpreferences)), this)
|
||||||
insulin.setIfSmaller(aapsLogger, hardLimits.maxBolus(), rh.gs(R.string.limitingextendedbolus, hardLimits.maxBolus(), rh.gs(R.string.hardlimit)), this)
|
insulin.setIfSmaller(hardLimits.maxBolus(), rh.gs(R.string.limitingextendedbolus, hardLimits.maxBolus(), rh.gs(R.string.hardlimit)), this)
|
||||||
val pump = activePlugin.activePump
|
val pump = activePlugin.activePump
|
||||||
val rounded = pump.pumpDescription.pumpType.determineCorrectExtendedBolusSize(insulin.value())
|
val rounded = pump.pumpDescription.pumpType.determineCorrectExtendedBolusSize(insulin.value())
|
||||||
insulin.setIfDifferent(aapsLogger, rounded, rh.gs(info.nightscout.core.ui.R.string.pumplimit), this)
|
insulin.setIfDifferent(rounded, rh.gs(info.nightscout.core.ui.R.string.pumplimit), this)
|
||||||
return insulin
|
return insulin
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun applyCarbsConstraints(carbs: Constraint<Int>): Constraint<Int> {
|
override fun applyCarbsConstraints(carbs: Constraint<Int>): Constraint<Int> {
|
||||||
carbs.setIfGreater(aapsLogger, 0, rh.gs(R.string.limitingcarbs, 0, rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), this)
|
carbs.setIfGreater(0, rh.gs(R.string.limitingcarbs, 0, rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), this)
|
||||||
val maxCarbs = sp.getInt(info.nightscout.core.utils.R.string.key_treatmentssafety_maxcarbs, 48)
|
val maxCarbs = sp.getInt(info.nightscout.core.utils.R.string.key_treatmentssafety_maxcarbs, 48)
|
||||||
carbs.setIfSmaller(aapsLogger, maxCarbs, rh.gs(R.string.limitingcarbs, maxCarbs, rh.gs(R.string.maxvalueinpreferences)), this)
|
carbs.setIfSmaller(maxCarbs, rh.gs(R.string.limitingcarbs, maxCarbs, rh.gs(R.string.maxvalueinpreferences)), this)
|
||||||
return carbs
|
return carbs
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> {
|
override fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> {
|
||||||
val apsMode = ApsMode.fromString(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name))
|
val apsMode = ApsMode.fromString(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name))
|
||||||
if (apsMode == ApsMode.LGS) maxIob.setIfSmaller(aapsLogger, HardLimits.MAX_IOB_LGS, rh.gs(info.nightscout.core.ui.R.string.limiting_iob, HardLimits.MAX_IOB_LGS, rh.gs(info.nightscout.core.ui.R.string.lowglucosesuspend)), this)
|
if (apsMode == ApsMode.LGS) maxIob.setIfSmaller(
|
||||||
|
HardLimits.MAX_IOB_LGS,
|
||||||
|
rh.gs(info.nightscout.core.ui.R.string.limiting_iob, HardLimits.MAX_IOB_LGS, rh.gs(info.nightscout.core.ui.R.string.lowglucosesuspend)),
|
||||||
|
this
|
||||||
|
)
|
||||||
return maxIob
|
return maxIob
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import android.os.Handler
|
||||||
import android.os.HandlerThread
|
import android.os.HandlerThread
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.Constraint
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.PluginConstraints
|
||||||
import info.nightscout.interfaces.notifications.Notification
|
import info.nightscout.interfaces.notifications.Notification
|
||||||
import info.nightscout.interfaces.plugin.PluginBase
|
import info.nightscout.interfaces.plugin.PluginBase
|
||||||
import info.nightscout.interfaces.plugin.PluginDescription
|
import info.nightscout.interfaces.plugin.PluginDescription
|
||||||
|
@ -54,7 +54,7 @@ class SignatureVerifierPlugin @Inject constructor(
|
||||||
.showInList(false)
|
.showInList(false)
|
||||||
.pluginName(R.string.signature_verifier),
|
.pluginName(R.string.signature_verifier),
|
||||||
aapsLogger, rh, injector
|
aapsLogger, rh, injector
|
||||||
), Constraints {
|
), PluginConstraints {
|
||||||
|
|
||||||
private var handler = Handler(HandlerThread(this::class.simpleName + "Handler").also { it.start() }.looper)
|
private var handler = Handler(HandlerThread(this::class.simpleName + "Handler").also { it.start() }.looper)
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ class SignatureVerifierPlugin @Inject constructor(
|
||||||
override fun isLoopInvocationAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isLoopInvocationAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
if (hasIllegalSignature()) {
|
if (hasIllegalSignature()) {
|
||||||
showNotification()
|
showNotification()
|
||||||
value.set(aapsLogger, false)
|
value.set(false)
|
||||||
}
|
}
|
||||||
if (shouldDownloadCerts()) {
|
if (shouldDownloadCerts()) {
|
||||||
handler.post {
|
handler.post {
|
||||||
|
|
|
@ -6,7 +6,7 @@ import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.annotations.OpenForTesting
|
import info.nightscout.annotations.OpenForTesting
|
||||||
import info.nightscout.interfaces.Constants
|
import info.nightscout.interfaces.Constants
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.Constraint
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.PluginConstraints
|
||||||
import info.nightscout.interfaces.notifications.Notification
|
import info.nightscout.interfaces.notifications.Notification
|
||||||
import info.nightscout.interfaces.plugin.PluginBase
|
import info.nightscout.interfaces.plugin.PluginBase
|
||||||
import info.nightscout.interfaces.plugin.PluginDescription
|
import info.nightscout.interfaces.plugin.PluginDescription
|
||||||
|
@ -34,13 +34,13 @@ class StorageConstraintPlugin @Inject constructor(
|
||||||
.showInList(false)
|
.showInList(false)
|
||||||
.pluginName(R.string.storage),
|
.pluginName(R.string.storage),
|
||||||
aapsLogger, rh, injector
|
aapsLogger, rh, injector
|
||||||
), Constraints {
|
), PluginConstraints {
|
||||||
|
|
||||||
override fun isClosedLoopAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isClosedLoopAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
val diskFree = availableInternalMemorySize()
|
val diskFree = availableInternalMemorySize()
|
||||||
if (diskFree < Constants.MINIMUM_FREE_SPACE) {
|
if (diskFree < Constants.MINIMUM_FREE_SPACE) {
|
||||||
aapsLogger.debug(LTag.CONSTRAINTS, "Closed loop disabled. Internal storage free (Mb):$diskFree")
|
aapsLogger.debug(LTag.CONSTRAINTS, "Closed loop disabled. Internal storage free (Mb):$diskFree")
|
||||||
value.set(aapsLogger, false, rh.gs(R.string.disk_full, Constants.MINIMUM_FREE_SPACE), this)
|
value.set(false, rh.gs(R.string.disk_full, Constants.MINIMUM_FREE_SPACE), this)
|
||||||
activeNames.addNotification(Notification.DISK_FULL, rh.gs(R.string.disk_full, Constants.MINIMUM_FREE_SPACE), Notification.NORMAL)
|
activeNames.addNotification(Notification.DISK_FULL, rh.gs(R.string.disk_full, Constants.MINIMUM_FREE_SPACE), Notification.NORMAL)
|
||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
|
|
|
@ -3,7 +3,7 @@ package info.nightscout.plugins.constraints.versionChecker
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.interfaces.Config
|
import info.nightscout.interfaces.Config
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.Constraint
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.PluginConstraints
|
||||||
import info.nightscout.interfaces.notifications.Notification
|
import info.nightscout.interfaces.notifications.Notification
|
||||||
import info.nightscout.interfaces.plugin.PluginBase
|
import info.nightscout.interfaces.plugin.PluginBase
|
||||||
import info.nightscout.interfaces.plugin.PluginDescription
|
import info.nightscout.interfaces.plugin.PluginDescription
|
||||||
|
@ -40,7 +40,7 @@ class VersionCheckerPlugin @Inject constructor(
|
||||||
.showInList(false)
|
.showInList(false)
|
||||||
.pluginName(R.string.version_checker),
|
.pluginName(R.string.version_checker),
|
||||||
aapsLogger, rh, injector
|
aapsLogger, rh, injector
|
||||||
), Constraints {
|
), PluginConstraints {
|
||||||
|
|
||||||
enum class GracePeriod(val warning: Long, val old: Long, val veryOld: Long) {
|
enum class GracePeriod(val warning: Long, val old: Long, val veryOld: Long) {
|
||||||
RELEASE(30, 60, 90),
|
RELEASE(30, 60, 90),
|
||||||
|
@ -64,16 +64,16 @@ class VersionCheckerPlugin @Inject constructor(
|
||||||
checkWarning()
|
checkWarning()
|
||||||
versionCheckerUtils.triggerCheckVersion()
|
versionCheckerUtils.triggerCheckVersion()
|
||||||
if (lastCheckOlderThan(gracePeriod.veryOld.daysToMillis()))
|
if (lastCheckOlderThan(gracePeriod.veryOld.daysToMillis()))
|
||||||
value.set(aapsLogger, false, rh.gs(R.string.very_old_version), this)
|
value.set(false, rh.gs(R.string.very_old_version), this)
|
||||||
val endDate = sp.getLong(rh.gs(info.nightscout.core.utils.R.string.key_app_expiration) + "_" + config.VERSION_NAME, 0)
|
val endDate = sp.getLong(rh.gs(info.nightscout.core.utils.R.string.key_app_expiration) + "_" + config.VERSION_NAME, 0)
|
||||||
if (endDate != 0L && dateUtil.now() > endDate)
|
if (endDate != 0L && dateUtil.now() > endDate)
|
||||||
value.set(aapsLogger, false, rh.gs(R.string.application_expired), this)
|
value.set(false, rh.gs(R.string.application_expired), this)
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> =
|
override fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> =
|
||||||
if (lastCheckOlderThan(gracePeriod.old.daysToMillis()))
|
if (lastCheckOlderThan(gracePeriod.old.daysToMillis()))
|
||||||
maxIob.set(aapsLogger, 0.0, rh.gs(R.string.old_version), this)
|
maxIob.set(0.0, rh.gs(R.string.old_version), this)
|
||||||
else
|
else
|
||||||
maxIob
|
maxIob
|
||||||
|
|
||||||
|
|
|
@ -2,16 +2,15 @@ package info.nightscout.plugins.constraints.bgQualityCheck
|
||||||
|
|
||||||
import dagger.android.AndroidInjector
|
import dagger.android.AndroidInjector
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||||
import info.nightscout.database.entities.GlucoseValue
|
import info.nightscout.database.entities.GlucoseValue
|
||||||
import info.nightscout.interfaces.aps.AutosensDataStore
|
import info.nightscout.interfaces.aps.AutosensDataStore
|
||||||
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
|
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
|
||||||
import info.nightscout.interfaces.iob.InMemoryGlucoseValue
|
import info.nightscout.interfaces.iob.InMemoryGlucoseValue
|
||||||
import info.nightscout.interfaces.iob.IobCobCalculator
|
import info.nightscout.interfaces.iob.IobCobCalculator
|
||||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||||
import info.nightscout.plugins.constraints.R
|
import info.nightscout.plugins.constraints.R
|
||||||
import info.nightscout.rx.bus.RxBus
|
|
||||||
import info.nightscout.shared.interfaces.ResourceHelper
|
import info.nightscout.shared.interfaces.ResourceHelper
|
||||||
import info.nightscout.shared.utils.DateUtil
|
import info.nightscout.shared.utils.DateUtil
|
||||||
import info.nightscout.shared.utils.T
|
import info.nightscout.shared.utils.T
|
||||||
|
@ -35,7 +34,13 @@ class BgQualityCheckPluginTest : TestBase() {
|
||||||
|
|
||||||
private lateinit var plugin: BgQualityCheckPlugin
|
private lateinit var plugin: BgQualityCheckPlugin
|
||||||
|
|
||||||
private val injector = HasAndroidInjector { AndroidInjector { } }
|
private val injector = HasAndroidInjector {
|
||||||
|
AndroidInjector {
|
||||||
|
if (it is ConstraintObject<*>) {
|
||||||
|
it.aapsLogger = aapsLogger
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
private val now = 100000000L
|
private val now = 100000000L
|
||||||
//private val autosensDataStore = AutosensDataStoreObject()
|
//private val autosensDataStore = AutosensDataStoreObject()
|
||||||
|
|
||||||
|
@ -46,7 +51,7 @@ class BgQualityCheckPluginTest : TestBase() {
|
||||||
injector,
|
injector,
|
||||||
aapsLogger,
|
aapsLogger,
|
||||||
rh,
|
rh,
|
||||||
RxBus(aapsSchedulers, aapsLogger),
|
rxBus,
|
||||||
iobCobCalculator,
|
iobCobCalculator,
|
||||||
aapsSchedulers,
|
aapsSchedulers,
|
||||||
fabricPrivacy,
|
fabricPrivacy,
|
||||||
|
@ -75,10 +80,46 @@ class BgQualityCheckPluginTest : TestBase() {
|
||||||
Assertions.assertEquals(R.drawable.ic_baseline_warning_24_yellow, plugin.icon())
|
Assertions.assertEquals(R.drawable.ic_baseline_warning_24_yellow, plugin.icon())
|
||||||
|
|
||||||
val superData: MutableList<GlucoseValue> = ArrayList()
|
val superData: MutableList<GlucoseValue> = ArrayList()
|
||||||
superData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
superData.add(
|
||||||
superData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
GlucoseValue(
|
||||||
superData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
raw = 0.0,
|
||||||
superData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
noise = 0.0,
|
||||||
|
value = 100.0,
|
||||||
|
timestamp = T.mins(20).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
superData.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 100.0,
|
||||||
|
timestamp = T.mins(15).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
superData.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 100.0,
|
||||||
|
timestamp = T.mins(10).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
superData.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 100.0,
|
||||||
|
timestamp = T.mins(5).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(superData)
|
`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(superData)
|
||||||
|
|
||||||
`when`(autosensDataStore.lastUsed5minCalculation).thenReturn(true)
|
`when`(autosensDataStore.lastUsed5minCalculation).thenReturn(true)
|
||||||
|
@ -205,16 +246,106 @@ class BgQualityCheckPluginTest : TestBase() {
|
||||||
|
|
||||||
// Flat data Libre
|
// Flat data Libre
|
||||||
val flatData: MutableList<GlucoseValue> = ArrayList()
|
val flatData: MutableList<GlucoseValue> = ArrayList()
|
||||||
flatData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = now + T.mins(0).msecs(), sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
flatData.add(
|
||||||
flatData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = now + T.mins(-5).msecs(), sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
GlucoseValue(
|
||||||
flatData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 101.0, timestamp = now + T.mins(-10).msecs(), sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
raw = 0.0,
|
||||||
flatData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = now + T.mins(-15).msecs(), sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
noise = 0.0,
|
||||||
flatData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = now + T.mins(-20).msecs(), sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
value = 100.0,
|
||||||
flatData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = now + T.mins(-25).msecs(), sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
timestamp = now + T.mins(0).msecs(),
|
||||||
flatData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 99.0, timestamp = now + T.mins(-30).msecs(), sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER,
|
||||||
flatData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = now + T.mins(-35).msecs(), sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
flatData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = now + T.mins(-40).msecs(), sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
)
|
||||||
flatData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = now + T.mins(-45).msecs(), sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
)
|
||||||
|
flatData.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 100.0,
|
||||||
|
timestamp = now + T.mins(-5).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flatData.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 101.0,
|
||||||
|
timestamp = now + T.mins(-10).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flatData.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 100.0,
|
||||||
|
timestamp = now + T.mins(-15).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flatData.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 100.0,
|
||||||
|
timestamp = now + T.mins(-20).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flatData.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 100.0,
|
||||||
|
timestamp = now + T.mins(-25).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flatData.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 99.0,
|
||||||
|
timestamp = now + T.mins(-30).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flatData.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 100.0,
|
||||||
|
timestamp = now + T.mins(-35).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flatData.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 100.0,
|
||||||
|
timestamp = now + T.mins(-40).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flatData.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 100.0,
|
||||||
|
timestamp = now + T.mins(-45).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(flatData)
|
`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(flatData)
|
||||||
`when`(iobCobCalculator.ads.lastBg()).thenReturn(InMemoryGlucoseValue(flatData[0]))
|
`when`(iobCobCalculator.ads.lastBg()).thenReturn(InMemoryGlucoseValue(flatData[0]))
|
||||||
|
|
||||||
|
@ -224,16 +355,106 @@ class BgQualityCheckPluginTest : TestBase() {
|
||||||
|
|
||||||
// Flat data Libre
|
// Flat data Libre
|
||||||
val flatDataDexcom: MutableList<GlucoseValue> = ArrayList()
|
val flatDataDexcom: MutableList<GlucoseValue> = ArrayList()
|
||||||
flatDataDexcom.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = now + T.mins(0).msecs(), sourceSensor = GlucoseValue.SourceSensor.DEXCOM_G6_NATIVE, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
flatDataDexcom.add(
|
||||||
flatDataDexcom.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = now + T.mins(-5).msecs(), sourceSensor = GlucoseValue.SourceSensor.DEXCOM_G6_NATIVE, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
GlucoseValue(
|
||||||
flatDataDexcom.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 101.0, timestamp = now + T.mins(-10).msecs(), sourceSensor = GlucoseValue.SourceSensor.DEXCOM_G6_NATIVE, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
raw = 0.0,
|
||||||
flatDataDexcom.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = now + T.mins(-15).msecs(), sourceSensor = GlucoseValue.SourceSensor.DEXCOM_G6_NATIVE, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
noise = 0.0,
|
||||||
flatDataDexcom.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = now + T.mins(-20).msecs(), sourceSensor = GlucoseValue.SourceSensor.DEXCOM_G6_NATIVE, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
value = 100.0,
|
||||||
flatDataDexcom.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = now + T.mins(-25).msecs(), sourceSensor = GlucoseValue.SourceSensor.DEXCOM_G6_NATIVE, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
timestamp = now + T.mins(0).msecs(),
|
||||||
flatDataDexcom.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 99.0, timestamp = now + T.mins(-30).msecs(), sourceSensor = GlucoseValue.SourceSensor.DEXCOM_G6_NATIVE, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
sourceSensor = GlucoseValue.SourceSensor.DEXCOM_G6_NATIVE,
|
||||||
flatDataDexcom.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = now + T.mins(-35).msecs(), sourceSensor = GlucoseValue.SourceSensor.DEXCOM_G6_NATIVE, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
flatDataDexcom.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = now + T.mins(-40).msecs(), sourceSensor = GlucoseValue.SourceSensor.DEXCOM_G6_NATIVE, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
)
|
||||||
flatDataDexcom.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = now + T.mins(-45).msecs(), sourceSensor = GlucoseValue.SourceSensor.DEXCOM_G6_NATIVE, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
)
|
||||||
|
flatDataDexcom.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 100.0,
|
||||||
|
timestamp = now + T.mins(-5).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.DEXCOM_G6_NATIVE,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flatDataDexcom.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 101.0,
|
||||||
|
timestamp = now + T.mins(-10).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.DEXCOM_G6_NATIVE,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flatDataDexcom.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 100.0,
|
||||||
|
timestamp = now + T.mins(-15).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.DEXCOM_G6_NATIVE,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flatDataDexcom.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 100.0,
|
||||||
|
timestamp = now + T.mins(-20).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.DEXCOM_G6_NATIVE,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flatDataDexcom.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 100.0,
|
||||||
|
timestamp = now + T.mins(-25).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.DEXCOM_G6_NATIVE,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flatDataDexcom.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 99.0,
|
||||||
|
timestamp = now + T.mins(-30).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.DEXCOM_G6_NATIVE,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flatDataDexcom.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 100.0,
|
||||||
|
timestamp = now + T.mins(-35).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.DEXCOM_G6_NATIVE,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flatDataDexcom.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 100.0,
|
||||||
|
timestamp = now + T.mins(-40).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.DEXCOM_G6_NATIVE,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flatDataDexcom.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 100.0,
|
||||||
|
timestamp = now + T.mins(-45).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.DEXCOM_G6_NATIVE,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(flatDataDexcom)
|
`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(flatDataDexcom)
|
||||||
`when`(iobCobCalculator.ads.lastBg()).thenReturn(InMemoryGlucoseValue(flatDataDexcom[0]))
|
`when`(iobCobCalculator.ads.lastBg()).thenReturn(InMemoryGlucoseValue(flatDataDexcom[0]))
|
||||||
|
|
||||||
|
@ -243,19 +464,100 @@ class BgQualityCheckPluginTest : TestBase() {
|
||||||
|
|
||||||
// not enough data
|
// not enough data
|
||||||
val incompleteData: MutableList<GlucoseValue> = ArrayList()
|
val incompleteData: MutableList<GlucoseValue> = ArrayList()
|
||||||
incompleteData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = now + T.mins(0).msecs(), sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
incompleteData.add(
|
||||||
incompleteData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = now + T.mins(-5).msecs(), sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 100.0,
|
||||||
|
timestamp = now + T.mins(0).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
incompleteData.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 100.0,
|
||||||
|
timestamp = now + T.mins(-5).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(incompleteData)
|
`when`(autosensDataStore.getBgReadingsDataTableCopy()).thenReturn(incompleteData)
|
||||||
`when`(iobCobCalculator.ads.lastBg()).thenReturn(InMemoryGlucoseValue(incompleteData[0]))
|
`when`(iobCobCalculator.ads.lastBg()).thenReturn(InMemoryGlucoseValue(incompleteData[0]))
|
||||||
plugin.processBgData()// must be more than 5 values
|
plugin.processBgData()// must be more than 5 values
|
||||||
Assertions.assertNotEquals(BgQualityCheck.State.FLAT, plugin.state)
|
Assertions.assertNotEquals(BgQualityCheck.State.FLAT, plugin.state)
|
||||||
flatData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 101.0, timestamp = now + T.mins(-10).msecs(), sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
flatData.add(
|
||||||
flatData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = now + T.mins(-15).msecs(), sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
GlucoseValue(
|
||||||
flatData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = now + T.mins(-20).msecs(), sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
raw = 0.0,
|
||||||
flatData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = now + T.mins(-25).msecs(), sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
noise = 0.0,
|
||||||
flatData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 99.0, timestamp = now + T.mins(-30).msecs(), sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
value = 101.0,
|
||||||
flatData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = now + T.mins(-35).msecs(), sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
timestamp = now + T.mins(-10).msecs(),
|
||||||
flatData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = now + T.mins(-40).msecs(), sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flatData.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 100.0,
|
||||||
|
timestamp = now + T.mins(-15).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flatData.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 100.0,
|
||||||
|
timestamp = now + T.mins(-20).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flatData.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 100.0,
|
||||||
|
timestamp = now + T.mins(-25).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flatData.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 99.0,
|
||||||
|
timestamp = now + T.mins(-30).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flatData.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 100.0,
|
||||||
|
timestamp = now + T.mins(-35).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flatData.add(
|
||||||
|
GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 100.0,
|
||||||
|
timestamp = now + T.mins(-40).msecs(),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
)
|
||||||
|
)
|
||||||
plugin.processBgData() // must be at least 45 min old
|
plugin.processBgData() // must be at least 45 min old
|
||||||
Assertions.assertNotEquals(BgQualityCheck.State.FLAT, plugin.state)
|
Assertions.assertNotEquals(BgQualityCheck.State.FLAT, plugin.state)
|
||||||
}
|
}
|
||||||
|
@ -263,13 +565,13 @@ class BgQualityCheckPluginTest : TestBase() {
|
||||||
@Test
|
@Test
|
||||||
fun applyMaxIOBConstraintsTest() {
|
fun applyMaxIOBConstraintsTest() {
|
||||||
plugin.state = BgQualityCheck.State.UNKNOWN
|
plugin.state = BgQualityCheck.State.UNKNOWN
|
||||||
Assertions.assertEquals(10.0, plugin.applyMaxIOBConstraints(Constraint(10.0)).value(), 0.001)
|
Assertions.assertEquals(10.0, plugin.applyMaxIOBConstraints(ConstraintObject(10.0, injector)).value(), 0.001)
|
||||||
plugin.state = BgQualityCheck.State.FIVE_MIN_DATA
|
plugin.state = BgQualityCheck.State.FIVE_MIN_DATA
|
||||||
Assertions.assertEquals(10.0, plugin.applyMaxIOBConstraints(Constraint(10.0)).value(), 0.001)
|
Assertions.assertEquals(10.0, plugin.applyMaxIOBConstraints(ConstraintObject(10.0, injector)).value(), 0.001)
|
||||||
plugin.state = BgQualityCheck.State.RECALCULATED
|
plugin.state = BgQualityCheck.State.RECALCULATED
|
||||||
Assertions.assertEquals(10.0, plugin.applyMaxIOBConstraints(Constraint(10.0)).value(), 0.001)
|
Assertions.assertEquals(10.0, plugin.applyMaxIOBConstraints(ConstraintObject(10.0, injector)).value(), 0.001)
|
||||||
plugin.state = BgQualityCheck.State.DOUBLED
|
plugin.state = BgQualityCheck.State.DOUBLED
|
||||||
Assertions.assertEquals(0.0, plugin.applyMaxIOBConstraints(Constraint(10.0)).value(), 0.001)
|
Assertions.assertEquals(0.0, plugin.applyMaxIOBConstraints(ConstraintObject(10.0, injector)).value(), 0.001)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -2,8 +2,8 @@ package info.nightscout.plugins.constraints.objectives
|
||||||
|
|
||||||
import dagger.android.AndroidInjector
|
import dagger.android.AndroidInjector
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.interfaces.Config
|
import info.nightscout.interfaces.Config
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
|
||||||
import info.nightscout.interfaces.constraints.Objectives
|
import info.nightscout.interfaces.constraints.Objectives
|
||||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||||
import info.nightscout.plugins.constraints.R
|
import info.nightscout.plugins.constraints.R
|
||||||
|
@ -35,6 +35,9 @@ class ObjectivesPluginTest : TestBase() {
|
||||||
it.rh = rh
|
it.rh = rh
|
||||||
it.dateUtil = dateUtil
|
it.dateUtil = dateUtil
|
||||||
}
|
}
|
||||||
|
if (it is ConstraintObject<*>) {
|
||||||
|
it.aapsLogger = aapsLogger
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,34 +52,30 @@ class ObjectivesPluginTest : TestBase() {
|
||||||
|
|
||||||
@Test fun notStartedObjectivesShouldLimitLoopInvocation() {
|
@Test fun notStartedObjectivesShouldLimitLoopInvocation() {
|
||||||
objectivesPlugin.objectives[Objectives.FIRST_OBJECTIVE].startedOn = 0
|
objectivesPlugin.objectives[Objectives.FIRST_OBJECTIVE].startedOn = 0
|
||||||
var c = Constraint(true)
|
val c = objectivesPlugin.isLoopInvocationAllowed(ConstraintObject(true, injector))
|
||||||
c = objectivesPlugin.isLoopInvocationAllowed(c)
|
Assertions.assertEquals("Objectives: Objective 1 not started", c.getReasons())
|
||||||
Assertions.assertEquals("Objectives: Objective 1 not started", c.getReasons(aapsLogger))
|
|
||||||
Assertions.assertEquals(false, c.value())
|
Assertions.assertEquals(false, c.value())
|
||||||
objectivesPlugin.objectives[Objectives.FIRST_OBJECTIVE].startedOn = dateUtil.now()
|
objectivesPlugin.objectives[Objectives.FIRST_OBJECTIVE].startedOn = dateUtil.now()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun notStartedObjective6ShouldLimitClosedLoop() {
|
@Test fun notStartedObjective6ShouldLimitClosedLoop() {
|
||||||
objectivesPlugin.objectives[Objectives.MAXIOB_ZERO_CL_OBJECTIVE].startedOn = 0
|
objectivesPlugin.objectives[Objectives.MAXIOB_ZERO_CL_OBJECTIVE].startedOn = 0
|
||||||
var c = Constraint(true)
|
val c = objectivesPlugin.isClosedLoopAllowed(ConstraintObject(true, injector))
|
||||||
c = objectivesPlugin.isClosedLoopAllowed(c)
|
Assertions.assertEquals(true, c.getReasons().contains("Objective 6 not started"))
|
||||||
Assertions.assertEquals(true, c.getReasons(aapsLogger).contains("Objective 6 not started"))
|
|
||||||
Assertions.assertEquals(false, c.value())
|
Assertions.assertEquals(false, c.value())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun notStartedObjective8ShouldLimitAutosensMode() {
|
@Test fun notStartedObjective8ShouldLimitAutosensMode() {
|
||||||
objectivesPlugin.objectives[Objectives.AUTOSENS_OBJECTIVE].startedOn = 0
|
objectivesPlugin.objectives[Objectives.AUTOSENS_OBJECTIVE].startedOn = 0
|
||||||
var c = Constraint(true)
|
val c = objectivesPlugin.isAutosensModeEnabled(ConstraintObject(true, injector))
|
||||||
c = objectivesPlugin.isAutosensModeEnabled(c)
|
Assertions.assertEquals(true, c.getReasons().contains("Objective 8 not started"))
|
||||||
Assertions.assertEquals(true, c.getReasons(aapsLogger).contains("Objective 8 not started"))
|
|
||||||
Assertions.assertEquals(false, c.value())
|
Assertions.assertEquals(false, c.value())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun notStartedObjective10ShouldLimitSMBMode() {
|
@Test fun notStartedObjective10ShouldLimitSMBMode() {
|
||||||
objectivesPlugin.objectives[Objectives.SMB_OBJECTIVE].startedOn = 0
|
objectivesPlugin.objectives[Objectives.SMB_OBJECTIVE].startedOn = 0
|
||||||
var c = Constraint(true)
|
val c = objectivesPlugin.isSMBModeEnabled(ConstraintObject(true, injector))
|
||||||
c = objectivesPlugin.isSMBModeEnabled(c)
|
Assertions.assertEquals(true, c.getReasons().contains("Objective 9 not started"))
|
||||||
Assertions.assertEquals(true, c.getReasons(aapsLogger).contains("Objective 9 not started"))
|
|
||||||
Assertions.assertEquals(false, c.value())
|
Assertions.assertEquals(false, c.value())
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,7 +2,7 @@ package info.nightscout.plugins.constraints.storage
|
||||||
|
|
||||||
import dagger.android.AndroidInjector
|
import dagger.android.AndroidInjector
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.interfaces.ui.UiInteraction
|
import info.nightscout.interfaces.ui.UiInteraction
|
||||||
import info.nightscout.rx.logging.AAPSLogger
|
import info.nightscout.rx.logging.AAPSLogger
|
||||||
import info.nightscout.shared.interfaces.ResourceHelper
|
import info.nightscout.shared.interfaces.ResourceHelper
|
||||||
|
@ -20,6 +20,13 @@ class StorageConstraintPluginTest : TestBase() {
|
||||||
@Mock lateinit var rh: ResourceHelper
|
@Mock lateinit var rh: ResourceHelper
|
||||||
@Mock lateinit var uiInteraction: UiInteraction
|
@Mock lateinit var uiInteraction: UiInteraction
|
||||||
|
|
||||||
|
private val injector = HasAndroidInjector {
|
||||||
|
AndroidInjector {
|
||||||
|
if (it is ConstraintObject<*>) {
|
||||||
|
it.aapsLogger = aapsLogger
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
private lateinit var storageConstraintPlugin: StorageConstraintPlugin
|
private lateinit var storageConstraintPlugin: StorageConstraintPlugin
|
||||||
|
|
||||||
@BeforeEach fun prepareMock() {
|
@BeforeEach fun prepareMock() {
|
||||||
|
@ -42,9 +49,9 @@ class StorageConstraintPluginTest : TestBase() {
|
||||||
val mocked = MockedStorageConstraintPlugin({ AndroidInjector { } }, aapsLogger, rh, uiInteraction)
|
val mocked = MockedStorageConstraintPlugin({ AndroidInjector { } }, aapsLogger, rh, uiInteraction)
|
||||||
// Set free space under 200(Mb) to disable loop
|
// Set free space under 200(Mb) to disable loop
|
||||||
mocked.memSize = 150L
|
mocked.memSize = 150L
|
||||||
Assertions.assertEquals(false, mocked.isClosedLoopAllowed(Constraint(true)).value())
|
Assertions.assertEquals(false, mocked.isClosedLoopAllowed(ConstraintObject(true, injector)).value())
|
||||||
// Set free space over 200(Mb) to enable loop
|
// Set free space over 200(Mb) to enable loop
|
||||||
mocked.memSize = 300L
|
mocked.memSize = 300L
|
||||||
Assertions.assertEquals(true, mocked.isClosedLoopAllowed(Constraint(true)).value())
|
Assertions.assertEquals(true, mocked.isClosedLoopAllowed(ConstraintObject(true, injector)).value())
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,7 +7,6 @@ import info.nightscout.interfaces.insulin.Insulin
|
||||||
import info.nightscout.interfaces.profile.ProfileFunction
|
import info.nightscout.interfaces.profile.ProfileFunction
|
||||||
import info.nightscout.interfaces.ui.UiInteraction
|
import info.nightscout.interfaces.ui.UiInteraction
|
||||||
import info.nightscout.interfaces.utils.HardLimits
|
import info.nightscout.interfaces.utils.HardLimits
|
||||||
import info.nightscout.rx.bus.RxBus
|
|
||||||
import info.nightscout.shared.interfaces.ResourceHelper
|
import info.nightscout.shared.interfaces.ResourceHelper
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
import info.nightscout.sharedtests.TestBase
|
import info.nightscout.sharedtests.TestBase
|
||||||
|
@ -29,7 +28,6 @@ class InsulinOrefFreePeakPluginTest : TestBase() {
|
||||||
|
|
||||||
@Mock lateinit var sp: SP
|
@Mock lateinit var sp: SP
|
||||||
@Mock lateinit var rh: ResourceHelper
|
@Mock lateinit var rh: ResourceHelper
|
||||||
@Mock lateinit var rxBus: RxBus
|
|
||||||
@Mock lateinit var profileFunction: ProfileFunction
|
@Mock lateinit var profileFunction: ProfileFunction
|
||||||
@Mock lateinit var config: Config
|
@Mock lateinit var config: Config
|
||||||
@Mock lateinit var hardLimits: HardLimits
|
@Mock lateinit var hardLimits: HardLimits
|
||||||
|
|
|
@ -27,6 +27,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.jjoe64.graphview.GraphView
|
import com.jjoe64.graphview.GraphView
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import dagger.android.support.DaggerFragment
|
import dagger.android.support.DaggerFragment
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.core.extensions.directionToIcon
|
import info.nightscout.core.extensions.directionToIcon
|
||||||
import info.nightscout.core.graph.OverviewData
|
import info.nightscout.core.graph.OverviewData
|
||||||
import info.nightscout.core.iob.displayText
|
import info.nightscout.core.iob.displayText
|
||||||
|
@ -49,8 +50,7 @@ import info.nightscout.interfaces.aps.Loop
|
||||||
import info.nightscout.interfaces.aps.VariableSensitivityResult
|
import info.nightscout.interfaces.aps.VariableSensitivityResult
|
||||||
import info.nightscout.interfaces.automation.Automation
|
import info.nightscout.interfaces.automation.Automation
|
||||||
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
|
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
|
||||||
import info.nightscout.interfaces.iob.GlucoseStatusProvider
|
import info.nightscout.interfaces.iob.GlucoseStatusProvider
|
||||||
import info.nightscout.interfaces.iob.IobCobCalculator
|
import info.nightscout.interfaces.iob.IobCobCalculator
|
||||||
import info.nightscout.interfaces.logging.UserEntryLogger
|
import info.nightscout.interfaces.logging.UserEntryLogger
|
||||||
|
@ -121,7 +121,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
@Inject lateinit var defaultValueHelper: DefaultValueHelper
|
@Inject lateinit var defaultValueHelper: DefaultValueHelper
|
||||||
@Inject lateinit var profileFunction: ProfileFunction
|
@Inject lateinit var profileFunction: ProfileFunction
|
||||||
@Inject lateinit var profileUtil: ProfileUtil
|
@Inject lateinit var profileUtil: ProfileUtil
|
||||||
@Inject lateinit var constraintChecker: Constraints
|
@Inject lateinit var constraintChecker: ConstraintsChecker
|
||||||
@Inject lateinit var statusLightHandler: StatusLightHandler
|
@Inject lateinit var statusLightHandler: StatusLightHandler
|
||||||
@Inject lateinit var processedDeviceStatusData: ProcessedDeviceStatusData
|
@Inject lateinit var processedDeviceStatusData: ProcessedDeviceStatusData
|
||||||
@Inject lateinit var nsSettingsStatus: NSSettingsStatus
|
@Inject lateinit var nsSettingsStatus: NSSettingsStatus
|
||||||
|
@ -516,7 +516,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
binding.buttonsLayout.quickWizardButton.visibility = View.VISIBLE
|
binding.buttonsLayout.quickWizardButton.visibility = View.VISIBLE
|
||||||
val wizard = quickWizardEntry.doCalc(profile, profileName, actualBg)
|
val wizard = quickWizardEntry.doCalc(profile, profileName, actualBg)
|
||||||
if (wizard.calculatedTotalInsulin > 0.0 && quickWizardEntry.carbs() > 0.0) {
|
if (wizard.calculatedTotalInsulin > 0.0 && quickWizardEntry.carbs() > 0.0) {
|
||||||
val carbsAfterConstraints = constraintChecker.applyCarbsConstraints(Constraint(quickWizardEntry.carbs())).value()
|
val carbsAfterConstraints = constraintChecker.applyCarbsConstraints(ConstraintObject(quickWizardEntry.carbs(), injector)).value()
|
||||||
activity?.let {
|
activity?.let {
|
||||||
if (abs(wizard.insulinAfterConstraints - wizard.calculatedTotalInsulin) >= pump.pumpDescription.pumpType.determineCorrectBolusStepSize(wizard.insulinAfterConstraints) || carbsAfterConstraints != quickWizardEntry.carbs()) {
|
if (abs(wizard.insulinAfterConstraints - wizard.calculatedTotalInsulin) >= pump.pumpDescription.pumpType.determineCorrectBolusStepSize(wizard.insulinAfterConstraints) || carbsAfterConstraints != quickWizardEntry.carbs()) {
|
||||||
OKDialog.show(it, rh.gs(info.nightscout.core.ui.R.string.treatmentdeliveryerror), rh.gs(R.string.constraints_violation) + "\n" + rh.gs(R.string.change_your_input))
|
OKDialog.show(it, rh.gs(info.nightscout.core.ui.R.string.treatmentdeliveryerror), rh.gs(R.string.constraints_violation) + "\n" + rh.gs(R.string.change_your_input))
|
||||||
|
|
|
@ -11,6 +11,7 @@ import androidx.work.WorkerParameters
|
||||||
import androidx.work.workDataOf
|
import androidx.work.workDataOf
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.annotations.OpenForTesting
|
import info.nightscout.annotations.OpenForTesting
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.core.events.EventNewNotification
|
import info.nightscout.core.events.EventNewNotification
|
||||||
import info.nightscout.core.iob.generateCOBString
|
import info.nightscout.core.iob.generateCOBString
|
||||||
import info.nightscout.core.iob.round
|
import info.nightscout.core.iob.round
|
||||||
|
@ -34,8 +35,7 @@ import info.nightscout.interfaces.Constants
|
||||||
import info.nightscout.interfaces.GlucoseUnit
|
import info.nightscout.interfaces.GlucoseUnit
|
||||||
import info.nightscout.interfaces.XDripBroadcast
|
import info.nightscout.interfaces.XDripBroadcast
|
||||||
import info.nightscout.interfaces.aps.Loop
|
import info.nightscout.interfaces.aps.Loop
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
|
||||||
import info.nightscout.interfaces.iob.GlucoseStatusProvider
|
import info.nightscout.interfaces.iob.GlucoseStatusProvider
|
||||||
import info.nightscout.interfaces.iob.IobCobCalculator
|
import info.nightscout.interfaces.iob.IobCobCalculator
|
||||||
import info.nightscout.interfaces.logging.UserEntryLogger
|
import info.nightscout.interfaces.logging.UserEntryLogger
|
||||||
|
@ -91,7 +91,7 @@ class SmsCommunicatorPlugin @Inject constructor(
|
||||||
private val smsManager: SmsManager?,
|
private val smsManager: SmsManager?,
|
||||||
private val aapsSchedulers: AapsSchedulers,
|
private val aapsSchedulers: AapsSchedulers,
|
||||||
private val sp: SP,
|
private val sp: SP,
|
||||||
private val constraintChecker: Constraints,
|
private val constraintChecker: ConstraintsChecker,
|
||||||
private val rxBus: RxBus,
|
private val rxBus: RxBus,
|
||||||
private val profileFunction: ProfileFunction,
|
private val profileFunction: ProfileFunction,
|
||||||
private val profileUtil: ProfileUtil,
|
private val profileUtil: ProfileUtil,
|
||||||
|
@ -732,7 +732,7 @@ class SmsCommunicatorPlugin @Inject constructor(
|
||||||
else if (tempBasalPct == 0 && divided[1] != "0%") sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
|
else if (tempBasalPct == 0 && divided[1] != "0%") sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
|
||||||
else if (duration <= 0 || duration % durationStep != 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.sms_wrong_tbr_duration, durationStep)))
|
else if (duration <= 0 || duration % durationStep != 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.sms_wrong_tbr_duration, durationStep)))
|
||||||
else {
|
else {
|
||||||
tempBasalPct = constraintChecker.applyBasalPercentConstraints(Constraint(tempBasalPct), profile).value()
|
tempBasalPct = constraintChecker.applyBasalPercentConstraints(ConstraintObject(tempBasalPct, injector), profile).value()
|
||||||
val passCode = generatePassCode()
|
val passCode = generatePassCode()
|
||||||
val reply = rh.gs(R.string.smscommunicator_basal_pct_reply_with_code, tempBasalPct, duration, passCode)
|
val reply = rh.gs(R.string.smscommunicator_basal_pct_reply_with_code, tempBasalPct, duration, passCode)
|
||||||
receivedSms.processed = true
|
receivedSms.processed = true
|
||||||
|
@ -787,7 +787,7 @@ class SmsCommunicatorPlugin @Inject constructor(
|
||||||
else if (tempBasal == 0.0 && divided[1] != "0") sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
|
else if (tempBasal == 0.0 && divided[1] != "0") sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
|
||||||
else if (duration <= 0 || duration % durationStep != 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.sms_wrong_tbr_duration, durationStep)))
|
else if (duration <= 0 || duration % durationStep != 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.sms_wrong_tbr_duration, durationStep)))
|
||||||
else {
|
else {
|
||||||
tempBasal = constraintChecker.applyBasalConstraints(Constraint(tempBasal), profile).value()
|
tempBasal = constraintChecker.applyBasalConstraints(ConstraintObject(tempBasal, injector), profile).value()
|
||||||
val passCode = generatePassCode()
|
val passCode = generatePassCode()
|
||||||
val reply = rh.gs(R.string.smscommunicator_basal_reply_with_code, tempBasal, duration, passCode)
|
val reply = rh.gs(R.string.smscommunicator_basal_reply_with_code, tempBasal, duration, passCode)
|
||||||
receivedSms.processed = true
|
receivedSms.processed = true
|
||||||
|
@ -864,7 +864,7 @@ class SmsCommunicatorPlugin @Inject constructor(
|
||||||
} else {
|
} else {
|
||||||
var extended = SafeParse.stringToDouble(divided[1])
|
var extended = SafeParse.stringToDouble(divided[1])
|
||||||
val duration = SafeParse.stringToInt(divided[2])
|
val duration = SafeParse.stringToInt(divided[2])
|
||||||
extended = constraintChecker.applyExtendedBolusConstraints(Constraint(extended)).value()
|
extended = constraintChecker.applyExtendedBolusConstraints(ConstraintObject(extended, injector)).value()
|
||||||
if (extended == 0.0 || duration == 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
|
if (extended == 0.0 || duration == 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
|
||||||
else {
|
else {
|
||||||
val passCode = generatePassCode()
|
val passCode = generatePassCode()
|
||||||
|
@ -918,7 +918,7 @@ class SmsCommunicatorPlugin @Inject constructor(
|
||||||
private fun processBOLUS(divided: Array<String>, receivedSms: Sms) {
|
private fun processBOLUS(divided: Array<String>, receivedSms: Sms) {
|
||||||
var bolus = SafeParse.stringToDouble(divided[1])
|
var bolus = SafeParse.stringToDouble(divided[1])
|
||||||
val isMeal = divided.size > 2 && divided[2].equals("MEAL", ignoreCase = true)
|
val isMeal = divided.size > 2 && divided[2].equals("MEAL", ignoreCase = true)
|
||||||
bolus = constraintChecker.applyBolusConstraints(Constraint(bolus)).value()
|
bolus = constraintChecker.applyBolusConstraints(ConstraintObject(bolus, injector)).value()
|
||||||
if (divided.size == 3 && !isMeal) {
|
if (divided.size == 3 && !isMeal) {
|
||||||
sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
|
sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
|
||||||
} else if (bolus > 0.0) {
|
} else if (bolus > 0.0) {
|
||||||
|
@ -1031,7 +1031,7 @@ class SmsCommunicatorPlugin @Inject constructor(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
grams = constraintChecker.applyCarbsConstraints(Constraint(grams)).value()
|
grams = constraintChecker.applyCarbsConstraints(ConstraintObject(grams, injector)).value()
|
||||||
if (grams == 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
|
if (grams == 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format)))
|
||||||
else {
|
else {
|
||||||
val passCode = generatePassCode()
|
val passCode = generatePassCode()
|
||||||
|
|
|
@ -3,6 +3,7 @@ package info.nightscout.plugins.general.wear.wearintegration
|
||||||
import android.app.NotificationManager
|
import android.app.NotificationManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.core.extensions.convertedToAbsolute
|
import info.nightscout.core.extensions.convertedToAbsolute
|
||||||
import info.nightscout.core.extensions.toStringShort
|
import info.nightscout.core.extensions.toStringShort
|
||||||
import info.nightscout.core.extensions.valueToUnits
|
import info.nightscout.core.extensions.valueToUnits
|
||||||
|
@ -33,8 +34,7 @@ import info.nightscout.interfaces.Config
|
||||||
import info.nightscout.interfaces.Constants
|
import info.nightscout.interfaces.Constants
|
||||||
import info.nightscout.interfaces.GlucoseUnit
|
import info.nightscout.interfaces.GlucoseUnit
|
||||||
import info.nightscout.interfaces.aps.Loop
|
import info.nightscout.interfaces.aps.Loop
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
|
||||||
import info.nightscout.interfaces.db.PersistenceLayer
|
import info.nightscout.interfaces.db.PersistenceLayer
|
||||||
import info.nightscout.interfaces.iob.GlucoseStatusProvider
|
import info.nightscout.interfaces.iob.GlucoseStatusProvider
|
||||||
import info.nightscout.interfaces.iob.InMemoryGlucoseValue
|
import info.nightscout.interfaces.iob.InMemoryGlucoseValue
|
||||||
|
@ -104,7 +104,7 @@ class DataHandlerMobile @Inject constructor(
|
||||||
private val defaultValueHelper: DefaultValueHelper,
|
private val defaultValueHelper: DefaultValueHelper,
|
||||||
private val trendCalculator: TrendCalculator,
|
private val trendCalculator: TrendCalculator,
|
||||||
private val dateUtil: DateUtil,
|
private val dateUtil: DateUtil,
|
||||||
private val constraintChecker: Constraints,
|
private val constraintChecker: ConstraintsChecker,
|
||||||
private val uel: UserEntryLogger,
|
private val uel: UserEntryLogger,
|
||||||
private val activePlugin: ActivePlugin,
|
private val activePlugin: ActivePlugin,
|
||||||
private val commandQueue: CommandQueue,
|
private val commandQueue: CommandQueue,
|
||||||
|
@ -269,7 +269,7 @@ class DataHandlerMobile @Inject constructor(
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
aapsLogger.debug(LTag.WEAR, "ActionFillConfirmed received $it from ${it.sourceNodeId}")
|
aapsLogger.debug(LTag.WEAR, "ActionFillConfirmed received $it from ${it.sourceNodeId}")
|
||||||
if (constraintChecker.applyBolusConstraints(Constraint(it.insulin)).value() - it.insulin != 0.0) {
|
if (constraintChecker.applyBolusConstraints(ConstraintObject(it.insulin, injector)).value() - it.insulin != 0.0) {
|
||||||
ToastUtils.showToastInUiThread(context, "aborting: previously applied constraint changed")
|
ToastUtils.showToastInUiThread(context, "aborting: previously applied constraint changed")
|
||||||
sendError("aborting: previously applied constraint changed")
|
sendError("aborting: previously applied constraint changed")
|
||||||
} else
|
} else
|
||||||
|
@ -383,7 +383,7 @@ class DataHandlerMobile @Inject constructor(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val carbsBeforeConstraints = command.carbs
|
val carbsBeforeConstraints = command.carbs
|
||||||
val carbsAfterConstraints = constraintChecker.applyCarbsConstraints(Constraint(carbsBeforeConstraints)).value()
|
val carbsAfterConstraints = constraintChecker.applyCarbsConstraints(ConstraintObject(carbsBeforeConstraints, injector)).value()
|
||||||
if (carbsAfterConstraints - carbsBeforeConstraints != 0) {
|
if (carbsAfterConstraints - carbsBeforeConstraints != 0) {
|
||||||
sendError(rh.gs(info.nightscout.core.ui.R.string.wizard_carbs_constraint))
|
sendError(rh.gs(info.nightscout.core.ui.R.string.wizard_carbs_constraint))
|
||||||
return
|
return
|
||||||
|
@ -480,7 +480,7 @@ class DataHandlerMobile @Inject constructor(
|
||||||
|
|
||||||
val wizard = quickWizardEntry.doCalc(profile, profileName, actualBg)
|
val wizard = quickWizardEntry.doCalc(profile, profileName, actualBg)
|
||||||
|
|
||||||
val carbsAfterConstraints = constraintChecker.applyCarbsConstraints(Constraint(quickWizardEntry.carbs())).value()
|
val carbsAfterConstraints = constraintChecker.applyCarbsConstraints(ConstraintObject(quickWizardEntry.carbs(), injector)).value()
|
||||||
if (carbsAfterConstraints != quickWizardEntry.carbs()) {
|
if (carbsAfterConstraints != quickWizardEntry.carbs()) {
|
||||||
sendError(rh.gs(info.nightscout.core.ui.R.string.wizard_carbs_constraint))
|
sendError(rh.gs(info.nightscout.core.ui.R.string.wizard_carbs_constraint))
|
||||||
return
|
return
|
||||||
|
@ -506,8 +506,8 @@ class DataHandlerMobile @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleBolusPreCheck(command: EventData.ActionBolusPreCheck) {
|
private fun handleBolusPreCheck(command: EventData.ActionBolusPreCheck) {
|
||||||
val insulinAfterConstraints = constraintChecker.applyBolusConstraints(Constraint(command.insulin)).value()
|
val insulinAfterConstraints = constraintChecker.applyBolusConstraints(ConstraintObject(command.insulin, injector)).value()
|
||||||
val carbsAfterConstraints = constraintChecker.applyCarbsConstraints(Constraint(command.carbs)).value()
|
val carbsAfterConstraints = constraintChecker.applyCarbsConstraints(ConstraintObject(command.carbs, injector)).value()
|
||||||
val pump = activePlugin.activePump
|
val pump = activePlugin.activePump
|
||||||
if (insulinAfterConstraints > 0 && (!pump.isInitialized() || pump.isSuspended() || loop.isDisconnected)) {
|
if (insulinAfterConstraints > 0 && (!pump.isInitialized() || pump.isSuspended() || loop.isDisconnected)) {
|
||||||
sendError(rh.gs(info.nightscout.core.ui.R.string.wizard_pump_not_available))
|
sendError(rh.gs(info.nightscout.core.ui.R.string.wizard_pump_not_available))
|
||||||
|
@ -530,7 +530,7 @@ class DataHandlerMobile @Inject constructor(
|
||||||
|
|
||||||
private fun handleECarbsPreCheck(command: EventData.ActionECarbsPreCheck) {
|
private fun handleECarbsPreCheck(command: EventData.ActionECarbsPreCheck) {
|
||||||
val startTimeStamp = System.currentTimeMillis() + T.mins(command.carbsTimeShift.toLong()).msecs()
|
val startTimeStamp = System.currentTimeMillis() + T.mins(command.carbsTimeShift.toLong()).msecs()
|
||||||
val carbsAfterConstraints = constraintChecker.applyCarbsConstraints(Constraint(command.carbs)).value()
|
val carbsAfterConstraints = constraintChecker.applyCarbsConstraints(ConstraintObject(command.carbs, injector)).value()
|
||||||
var message = rh.gs(info.nightscout.core.ui.R.string.carbs) + ": " + carbsAfterConstraints + rh.gs(R.string.grams_short) +
|
var message = rh.gs(info.nightscout.core.ui.R.string.carbs) + ": " + carbsAfterConstraints + rh.gs(R.string.grams_short) +
|
||||||
"\n" + rh.gs(info.nightscout.core.ui.R.string.time) + ": " + dateUtil.timeString(startTimeStamp) +
|
"\n" + rh.gs(info.nightscout.core.ui.R.string.time) + ": " + dateUtil.timeString(startTimeStamp) +
|
||||||
"\n" + rh.gs(info.nightscout.core.ui.R.string.duration) + ": " + command.duration + rh.gs(R.string.hour_short)
|
"\n" + rh.gs(info.nightscout.core.ui.R.string.duration) + ": " + command.duration + rh.gs(R.string.hour_short)
|
||||||
|
@ -558,7 +558,7 @@ class DataHandlerMobile @Inject constructor(
|
||||||
3 -> sp.getDouble("fill_button3", 0.0)
|
3 -> sp.getDouble("fill_button3", 0.0)
|
||||||
else -> return
|
else -> return
|
||||||
}
|
}
|
||||||
val insulinAfterConstraints = constraintChecker.applyBolusConstraints(Constraint(amount)).value()
|
val insulinAfterConstraints = constraintChecker.applyBolusConstraints(ConstraintObject(amount, injector)).value()
|
||||||
var message = rh.gs(info.nightscout.core.ui.R.string.prime_fill) + ": " + insulinAfterConstraints + rh.gs(R.string.units_short)
|
var message = rh.gs(info.nightscout.core.ui.R.string.prime_fill) + ": " + insulinAfterConstraints + rh.gs(R.string.units_short)
|
||||||
if (insulinAfterConstraints - amount != 0.0) message += "\n" + rh.gs(info.nightscout.core.ui.R.string.constraint_applied)
|
if (insulinAfterConstraints - amount != 0.0) message += "\n" + rh.gs(info.nightscout.core.ui.R.string.constraint_applied)
|
||||||
rxBus.send(
|
rxBus.send(
|
||||||
|
@ -572,7 +572,7 @@ class DataHandlerMobile @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleFillPreCheck(command: EventData.ActionFillPreCheck) {
|
private fun handleFillPreCheck(command: EventData.ActionFillPreCheck) {
|
||||||
val insulinAfterConstraints = constraintChecker.applyBolusConstraints(Constraint(command.insulin)).value()
|
val insulinAfterConstraints = constraintChecker.applyBolusConstraints(ConstraintObject(command.insulin, injector)).value()
|
||||||
var message = rh.gs(info.nightscout.core.ui.R.string.prime_fill) + ": " + insulinAfterConstraints + rh.gs(R.string.units_short)
|
var message = rh.gs(info.nightscout.core.ui.R.string.prime_fill) + ": " + insulinAfterConstraints + rh.gs(R.string.units_short)
|
||||||
if (insulinAfterConstraints - command.insulin != 0.0) message += "\n" + rh.gs(info.nightscout.core.ui.R.string.constraint_applied)
|
if (insulinAfterConstraints - command.insulin != 0.0) message += "\n" + rh.gs(info.nightscout.core.ui.R.string.constraint_applied)
|
||||||
rxBus.send(
|
rxBus.send(
|
||||||
|
|
|
@ -4,6 +4,7 @@ import android.telephony.SmsManager
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import dagger.android.AndroidInjector
|
import dagger.android.AndroidInjector
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.database.entities.GlucoseValue
|
import info.nightscout.database.entities.GlucoseValue
|
||||||
import info.nightscout.database.impl.AppRepository
|
import info.nightscout.database.impl.AppRepository
|
||||||
import info.nightscout.database.impl.transactions.CancelCurrentOfflineEventIfAnyTransaction
|
import info.nightscout.database.impl.transactions.CancelCurrentOfflineEventIfAnyTransaction
|
||||||
|
@ -16,8 +17,7 @@ import info.nightscout.interfaces.Constants
|
||||||
import info.nightscout.interfaces.XDripBroadcast
|
import info.nightscout.interfaces.XDripBroadcast
|
||||||
import info.nightscout.interfaces.aps.AutosensDataStore
|
import info.nightscout.interfaces.aps.AutosensDataStore
|
||||||
import info.nightscout.interfaces.aps.Loop
|
import info.nightscout.interfaces.aps.Loop
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
|
||||||
import info.nightscout.interfaces.iob.CobInfo
|
import info.nightscout.interfaces.iob.CobInfo
|
||||||
import info.nightscout.interfaces.iob.InMemoryGlucoseValue
|
import info.nightscout.interfaces.iob.InMemoryGlucoseValue
|
||||||
import info.nightscout.interfaces.iob.IobTotal
|
import info.nightscout.interfaces.iob.IobTotal
|
||||||
|
@ -48,7 +48,7 @@ import org.mockito.invocation.InvocationOnMock
|
||||||
@Suppress("SpellCheckingInspection")
|
@Suppress("SpellCheckingInspection")
|
||||||
class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
||||||
|
|
||||||
@Mock lateinit var constraintChecker: Constraints
|
@Mock lateinit var constraintChecker: ConstraintsChecker
|
||||||
@Mock lateinit var commandQueue: CommandQueue
|
@Mock lateinit var commandQueue: CommandQueue
|
||||||
@Mock lateinit var loop: Loop
|
@Mock lateinit var loop: Loop
|
||||||
@Mock lateinit var profileSource: ProfileSource
|
@Mock lateinit var profileSource: ProfileSource
|
||||||
|
@ -62,6 +62,9 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
||||||
|
|
||||||
private var injector: HasAndroidInjector = HasAndroidInjector {
|
private var injector: HasAndroidInjector = HasAndroidInjector {
|
||||||
AndroidInjector {
|
AndroidInjector {
|
||||||
|
if (it is ConstraintObject<*>) {
|
||||||
|
it.aapsLogger = aapsLogger
|
||||||
|
}
|
||||||
if (it is PumpEnactResult) {
|
if (it is PumpEnactResult) {
|
||||||
it.context = context
|
it.context = context
|
||||||
}
|
}
|
||||||
|
@ -836,7 +839,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
||||||
smsCommunicatorPlugin.processSms(sms)
|
smsCommunicatorPlugin.processSms(sms)
|
||||||
assertThat(smsCommunicatorPlugin.messages[0].text).isEqualTo("BASAL 20% 20")
|
assertThat(smsCommunicatorPlugin.messages[0].text).isEqualTo("BASAL 20% 20")
|
||||||
assertThat(smsCommunicatorPlugin.messages[1].text).isEqualTo("TBR duration must be a multiple of 30 minutes and greater than 0.")
|
assertThat(smsCommunicatorPlugin.messages[1].text).isEqualTo("TBR duration must be a multiple of 30 minutes and greater than 0.")
|
||||||
`when`(constraintChecker.applyBasalPercentConstraints(anyObject(), anyObject())).thenReturn(Constraint(20))
|
`when`(constraintChecker.applyBasalPercentConstraints(anyObject(), anyObject())).thenReturn(ConstraintObject(20, injector))
|
||||||
|
|
||||||
//BASAL 20% 30
|
//BASAL 20% 30
|
||||||
smsCommunicatorPlugin.messages = ArrayList()
|
smsCommunicatorPlugin.messages = ArrayList()
|
||||||
|
@ -862,7 +865,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
||||||
smsCommunicatorPlugin.processSms(sms)
|
smsCommunicatorPlugin.processSms(sms)
|
||||||
assertThat(smsCommunicatorPlugin.messages[0].text).isEqualTo("BASAL 1 0")
|
assertThat(smsCommunicatorPlugin.messages[0].text).isEqualTo("BASAL 1 0")
|
||||||
assertThat(smsCommunicatorPlugin.messages[1].text).isEqualTo("TBR duration must be a multiple of 30 minutes and greater than 0.")
|
assertThat(smsCommunicatorPlugin.messages[1].text).isEqualTo("TBR duration must be a multiple of 30 minutes and greater than 0.")
|
||||||
`when`(constraintChecker.applyBasalConstraints(anyObject(), anyObject())).thenReturn(Constraint(1.0))
|
`when`(constraintChecker.applyBasalConstraints(anyObject(), anyObject())).thenReturn(ConstraintObject(1.0, injector))
|
||||||
|
|
||||||
//BASAL 1 20
|
//BASAL 1 20
|
||||||
smsCommunicatorPlugin.messages = ArrayList()
|
smsCommunicatorPlugin.messages = ArrayList()
|
||||||
|
@ -870,7 +873,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
||||||
smsCommunicatorPlugin.processSms(sms)
|
smsCommunicatorPlugin.processSms(sms)
|
||||||
assertThat(smsCommunicatorPlugin.messages[0].text).isEqualTo("BASAL 1 20")
|
assertThat(smsCommunicatorPlugin.messages[0].text).isEqualTo("BASAL 1 20")
|
||||||
assertThat(smsCommunicatorPlugin.messages[1].text).isEqualTo("TBR duration must be a multiple of 30 minutes and greater than 0.")
|
assertThat(smsCommunicatorPlugin.messages[1].text).isEqualTo("TBR duration must be a multiple of 30 minutes and greater than 0.")
|
||||||
`when`(constraintChecker.applyBasalConstraints(anyObject(), anyObject())).thenReturn(Constraint(1.0))
|
`when`(constraintChecker.applyBasalConstraints(anyObject(), anyObject())).thenReturn(ConstraintObject(1.0, injector))
|
||||||
|
|
||||||
//BASAL 1 30
|
//BASAL 1 30
|
||||||
smsCommunicatorPlugin.messages = ArrayList()
|
smsCommunicatorPlugin.messages = ArrayList()
|
||||||
|
@ -918,7 +921,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
||||||
smsCommunicatorPlugin.processSms(sms)
|
smsCommunicatorPlugin.processSms(sms)
|
||||||
assertThat(smsCommunicatorPlugin.messages[0].text).isEqualTo("EXTENDED a%")
|
assertThat(smsCommunicatorPlugin.messages[0].text).isEqualTo("EXTENDED a%")
|
||||||
assertThat(smsCommunicatorPlugin.messages[1].text).isEqualTo("Wrong format")
|
assertThat(smsCommunicatorPlugin.messages[1].text).isEqualTo("Wrong format")
|
||||||
`when`(constraintChecker.applyExtendedBolusConstraints(anyObject())).thenReturn(Constraint(1.0))
|
`when`(constraintChecker.applyExtendedBolusConstraints(anyObject())).thenReturn(ConstraintObject(1.0, injector))
|
||||||
|
|
||||||
//EXTENDED 1 0
|
//EXTENDED 1 0
|
||||||
smsCommunicatorPlugin.messages = ArrayList()
|
smsCommunicatorPlugin.messages = ArrayList()
|
||||||
|
@ -955,7 +958,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
||||||
smsCommunicatorPlugin.processSms(sms)
|
smsCommunicatorPlugin.processSms(sms)
|
||||||
assertThat(smsCommunicatorPlugin.messages[0].text).isEqualTo("BOLUS")
|
assertThat(smsCommunicatorPlugin.messages[0].text).isEqualTo("BOLUS")
|
||||||
assertThat(smsCommunicatorPlugin.messages[1].text).isEqualTo("Wrong format")
|
assertThat(smsCommunicatorPlugin.messages[1].text).isEqualTo("Wrong format")
|
||||||
`when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(Constraint(1.0))
|
`when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(ConstraintObject(1.0, injector))
|
||||||
`when`(dateUtilMocked.now()).thenReturn(1000L)
|
`when`(dateUtilMocked.now()).thenReturn(1000L)
|
||||||
`when`(sp.getLong(R.string.key_smscommunicator_remote_bolus_min_distance, T.msecs(Constants.remoteBolusMinDistance).mins())).thenReturn(15L)
|
`when`(sp.getLong(R.string.key_smscommunicator_remote_bolus_min_distance, T.msecs(Constants.remoteBolusMinDistance).mins())).thenReturn(15L)
|
||||||
//BOLUS 1
|
//BOLUS 1
|
||||||
|
@ -964,7 +967,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
||||||
smsCommunicatorPlugin.processSms(sms)
|
smsCommunicatorPlugin.processSms(sms)
|
||||||
assertThat(smsCommunicatorPlugin.messages[0].text).isEqualTo("BOLUS 1")
|
assertThat(smsCommunicatorPlugin.messages[0].text).isEqualTo("BOLUS 1")
|
||||||
assertThat(smsCommunicatorPlugin.messages[1].text).isEqualTo("Remote bolus not available. Try again later.")
|
assertThat(smsCommunicatorPlugin.messages[1].text).isEqualTo("Remote bolus not available. Try again later.")
|
||||||
`when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(Constraint(0.0))
|
`when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(ConstraintObject(0.0, injector))
|
||||||
`when`(dateUtilMocked.now()).thenReturn(Constants.remoteBolusMinDistance + 1002L)
|
`when`(dateUtilMocked.now()).thenReturn(Constants.remoteBolusMinDistance + 1002L)
|
||||||
|
|
||||||
//BOLUS 0
|
//BOLUS 0
|
||||||
|
@ -980,8 +983,8 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
||||||
smsCommunicatorPlugin.processSms(sms)
|
smsCommunicatorPlugin.processSms(sms)
|
||||||
assertThat(smsCommunicatorPlugin.messages[0].text).isEqualTo("BOLUS a")
|
assertThat(smsCommunicatorPlugin.messages[0].text).isEqualTo("BOLUS a")
|
||||||
assertThat(smsCommunicatorPlugin.messages[1].text).isEqualTo("Wrong format")
|
assertThat(smsCommunicatorPlugin.messages[1].text).isEqualTo("Wrong format")
|
||||||
`when`(constraintChecker.applyExtendedBolusConstraints(anyObject())).thenReturn(Constraint(1.0))
|
`when`(constraintChecker.applyExtendedBolusConstraints(anyObject())).thenReturn(ConstraintObject(1.0, injector))
|
||||||
`when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(Constraint(1.0))
|
`when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(ConstraintObject(1.0, injector))
|
||||||
|
|
||||||
//BOLUS 1
|
//BOLUS 1
|
||||||
smsCommunicatorPlugin.messages = ArrayList()
|
smsCommunicatorPlugin.messages = ArrayList()
|
||||||
|
@ -1078,7 +1081,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
||||||
smsCommunicatorPlugin.processSms(sms)
|
smsCommunicatorPlugin.processSms(sms)
|
||||||
assertThat(smsCommunicatorPlugin.messages[0].text).isEqualTo("CARBS")
|
assertThat(smsCommunicatorPlugin.messages[0].text).isEqualTo("CARBS")
|
||||||
assertThat(smsCommunicatorPlugin.messages[1].text).isEqualTo("Wrong format")
|
assertThat(smsCommunicatorPlugin.messages[1].text).isEqualTo("Wrong format")
|
||||||
`when`(constraintChecker.applyCarbsConstraints(anyObject())).thenReturn(Constraint(0))
|
`when`(constraintChecker.applyCarbsConstraints(anyObject())).thenReturn(ConstraintObject(0, injector))
|
||||||
|
|
||||||
//CARBS 0
|
//CARBS 0
|
||||||
smsCommunicatorPlugin.messages = ArrayList()
|
smsCommunicatorPlugin.messages = ArrayList()
|
||||||
|
@ -1086,7 +1089,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
||||||
smsCommunicatorPlugin.processSms(sms)
|
smsCommunicatorPlugin.processSms(sms)
|
||||||
assertThat(smsCommunicatorPlugin.messages[0].text).isEqualTo("CARBS 0")
|
assertThat(smsCommunicatorPlugin.messages[0].text).isEqualTo("CARBS 0")
|
||||||
assertThat(smsCommunicatorPlugin.messages[1].text).isEqualTo("Wrong format")
|
assertThat(smsCommunicatorPlugin.messages[1].text).isEqualTo("Wrong format")
|
||||||
`when`(constraintChecker.applyCarbsConstraints(anyObject())).thenReturn(Constraint(1))
|
`when`(constraintChecker.applyCarbsConstraints(anyObject())).thenReturn(ConstraintObject(1, injector))
|
||||||
|
|
||||||
//CARBS 1
|
//CARBS 1
|
||||||
smsCommunicatorPlugin.messages = ArrayList()
|
smsCommunicatorPlugin.messages = ArrayList()
|
||||||
|
|
|
@ -12,6 +12,7 @@ import info.nightscout.plugins.iob.iobCobCalculator.data.AutosensDataStoreObject
|
||||||
import info.nightscout.shared.interfaces.ResourceHelper
|
import info.nightscout.shared.interfaces.ResourceHelper
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
import info.nightscout.shared.utils.DateUtil
|
import info.nightscout.shared.utils.DateUtil
|
||||||
|
import info.nightscout.shared.utils.DateUtilImpl
|
||||||
import info.nightscout.shared.utils.T
|
import info.nightscout.shared.utils.T
|
||||||
import info.nightscout.sharedtests.TestBase
|
import info.nightscout.sharedtests.TestBase
|
||||||
import org.junit.jupiter.api.Assertions
|
import org.junit.jupiter.api.Assertions
|
||||||
|
@ -46,7 +47,7 @@ class AutosensDataStoreTest : TestBase() {
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
fun mock() {
|
fun mock() {
|
||||||
dateUtil = DateUtil(context)
|
dateUtil = DateUtilImpl(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -12,7 +12,7 @@ import info.nightscout.interfaces.aps.AutosensResult
|
||||||
import info.nightscout.interfaces.aps.SMBDefaults
|
import info.nightscout.interfaces.aps.SMBDefaults
|
||||||
import info.nightscout.interfaces.aps.Sensitivity.SensitivityType
|
import info.nightscout.interfaces.aps.Sensitivity.SensitivityType
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.Constraint
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.PluginConstraints
|
||||||
import info.nightscout.interfaces.plugin.PluginDescription
|
import info.nightscout.interfaces.plugin.PluginDescription
|
||||||
import info.nightscout.interfaces.plugin.PluginType
|
import info.nightscout.interfaces.plugin.PluginType
|
||||||
import info.nightscout.interfaces.profile.ProfileFunction
|
import info.nightscout.interfaces.profile.ProfileFunction
|
||||||
|
@ -51,7 +51,7 @@ class SensitivityOref1Plugin @Inject constructor(
|
||||||
.description(R.string.description_sensitivity_oref1)
|
.description(R.string.description_sensitivity_oref1)
|
||||||
.setDefault(),
|
.setDefault(),
|
||||||
injector, aapsLogger, rh, sp
|
injector, aapsLogger, rh, sp
|
||||||
), Constraints {
|
), PluginConstraints {
|
||||||
|
|
||||||
override fun detectSensitivity(ads: AutosensDataStore, fromTime: Long, toTime: Long): AutosensResult {
|
override fun detectSensitivity(ads: AutosensDataStore, fromTime: Long, toTime: Long): AutosensResult {
|
||||||
val profile = profileFunction.getProfile()
|
val profile = profileFunction.getProfile()
|
||||||
|
@ -260,7 +260,7 @@ class SensitivityOref1Plugin @Inject constructor(
|
||||||
get() = SensitivityType.SENSITIVITY_OREF1
|
get() = SensitivityType.SENSITIVITY_OREF1
|
||||||
|
|
||||||
override fun isUAMEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
override fun isUAMEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||||
if (!isEnabled()) value.set(aapsLogger, false, rh.gs(R.string.uam_disabled_oref1_not_selected), this)
|
if (!isEnabled()) value.set(false, rh.gs(R.string.uam_disabled_oref1_not_selected), this)
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,7 +3,6 @@ package info.nightscout.plugins.sync.nsclient
|
||||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||||
import info.nightscout.interfaces.receivers.ReceiverStatusStore
|
import info.nightscout.interfaces.receivers.ReceiverStatusStore
|
||||||
import info.nightscout.plugins.sync.R
|
import info.nightscout.plugins.sync.R
|
||||||
import info.nightscout.rx.bus.RxBus
|
|
||||||
import info.nightscout.rx.events.EventChargingState
|
import info.nightscout.rx.events.EventChargingState
|
||||||
import info.nightscout.rx.events.EventNetworkChange
|
import info.nightscout.rx.events.EventNetworkChange
|
||||||
import info.nightscout.shared.interfaces.ResourceHelper
|
import info.nightscout.shared.interfaces.ResourceHelper
|
||||||
|
@ -20,7 +19,6 @@ class ReceiverDelegateTest : TestBase() {
|
||||||
@Mock lateinit var sp: SP
|
@Mock lateinit var sp: SP
|
||||||
@Mock lateinit var rh: ResourceHelper
|
@Mock lateinit var rh: ResourceHelper
|
||||||
@Mock lateinit var fabricPrivacy: FabricPrivacy
|
@Mock lateinit var fabricPrivacy: FabricPrivacy
|
||||||
private val rxBus = RxBus(aapsSchedulers, aapsLogger)
|
|
||||||
|
|
||||||
@Mock private lateinit var receiverStatusStore: ReceiverStatusStore
|
@Mock private lateinit var receiverStatusStore: ReceiverStatusStore
|
||||||
private lateinit var sut: ReceiverDelegate
|
private lateinit var sut: ReceiverDelegate
|
||||||
|
|
|
@ -10,7 +10,6 @@ import info.nightscout.interfaces.plugin.ActivePlugin
|
||||||
import info.nightscout.interfaces.sync.NsClient
|
import info.nightscout.interfaces.sync.NsClient
|
||||||
import info.nightscout.plugins.sync.nsclientV3.DataSyncSelectorV3
|
import info.nightscout.plugins.sync.nsclientV3.DataSyncSelectorV3
|
||||||
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
|
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
|
||||||
import info.nightscout.rx.bus.RxBus
|
|
||||||
import info.nightscout.sharedtests.TestBase
|
import info.nightscout.sharedtests.TestBase
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
|
@ -30,7 +29,6 @@ internal class DataSyncWorkerTest : TestBase() {
|
||||||
@Mock lateinit var dataSyncSelectorV3: DataSyncSelectorV3
|
@Mock lateinit var dataSyncSelectorV3: DataSyncSelectorV3
|
||||||
@Mock lateinit var activePlugin: ActivePlugin
|
@Mock lateinit var activePlugin: ActivePlugin
|
||||||
@Mock lateinit var nsClient: NsClient
|
@Mock lateinit var nsClient: NsClient
|
||||||
@Mock lateinit var rxBus: RxBus
|
|
||||||
@Mock lateinit var nsClientV3Plugin: NSClientV3Plugin
|
@Mock lateinit var nsClientV3Plugin: NSClientV3Plugin
|
||||||
@Mock lateinit var context: ContextWithInjector
|
@Mock lateinit var context: ContextWithInjector
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,6 @@ import info.nightscout.plugins.sync.nsclient.data.NSDeviceStatusHandler
|
||||||
import info.nightscout.plugins.sync.nsclientV3.DataSyncSelectorV3
|
import info.nightscout.plugins.sync.nsclientV3.DataSyncSelectorV3
|
||||||
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
|
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
|
||||||
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSSvgV3
|
import info.nightscout.plugins.sync.nsclientV3.extensions.toNSSvgV3
|
||||||
import info.nightscout.rx.bus.RxBus
|
|
||||||
import info.nightscout.sdk.interfaces.NSAndroidClient
|
import info.nightscout.sdk.interfaces.NSAndroidClient
|
||||||
import info.nightscout.sdk.remotemodel.LastModified
|
import info.nightscout.sdk.remotemodel.LastModified
|
||||||
import info.nightscout.shared.interfaces.ResourceHelper
|
import info.nightscout.shared.interfaces.ResourceHelper
|
||||||
|
@ -66,7 +65,6 @@ internal class LoadBgWorkerTest : TestBase() {
|
||||||
@Mock lateinit var nsIncomingDataProcessor: NsIncomingDataProcessor
|
@Mock lateinit var nsIncomingDataProcessor: NsIncomingDataProcessor
|
||||||
@Mock lateinit var context: ContextWithInjector
|
@Mock lateinit var context: ContextWithInjector
|
||||||
|
|
||||||
private val rxBus: RxBus = RxBus(aapsSchedulers, aapsLogger)
|
|
||||||
private lateinit var nsClientV3Plugin: NSClientV3Plugin
|
private lateinit var nsClientV3Plugin: NSClientV3Plugin
|
||||||
private lateinit var receiverDelegate: ReceiverDelegate
|
private lateinit var receiverDelegate: ReceiverDelegate
|
||||||
private lateinit var dataWorkerStorage: DataWorkerStorage
|
private lateinit var dataWorkerStorage: DataWorkerStorage
|
||||||
|
|
|
@ -22,7 +22,7 @@ import javax.inject.Singleton;
|
||||||
import dagger.android.HasAndroidInjector;
|
import dagger.android.HasAndroidInjector;
|
||||||
import info.nightscout.core.utils.fabric.InstanceId;
|
import info.nightscout.core.utils.fabric.InstanceId;
|
||||||
import info.nightscout.interfaces.constraints.Constraint;
|
import info.nightscout.interfaces.constraints.Constraint;
|
||||||
import info.nightscout.interfaces.constraints.Constraints;
|
import info.nightscout.interfaces.constraints.PluginConstraints;
|
||||||
import info.nightscout.interfaces.notifications.Notification;
|
import info.nightscout.interfaces.notifications.Notification;
|
||||||
import info.nightscout.interfaces.plugin.PluginDescription;
|
import info.nightscout.interfaces.plugin.PluginDescription;
|
||||||
import info.nightscout.interfaces.plugin.PluginType;
|
import info.nightscout.interfaces.plugin.PluginType;
|
||||||
|
@ -86,23 +86,41 @@ import info.nightscout.shared.utils.T;
|
||||||
* Created by mike on 05.08.2016.
|
* Created by mike on 05.08.2016.
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class ComboPlugin extends PumpPluginBase implements Pump, Constraints {
|
public class ComboPlugin extends PumpPluginBase implements Pump, PluginConstraints {
|
||||||
|
private final static PumpDescription pumpDescription = new PumpDescription();
|
||||||
|
@NonNull
|
||||||
|
private static final ComboPump pump = new ComboPump();
|
||||||
// collaborators
|
// collaborators
|
||||||
private final ProfileFunction profileFunction;
|
private final ProfileFunction profileFunction;
|
||||||
private final SP sp;
|
private final SP sp;
|
||||||
private RxBus rxBus;
|
|
||||||
private final CommandQueue commandQueue;
|
private final CommandQueue commandQueue;
|
||||||
private final PumpSync pumpSync;
|
private final PumpSync pumpSync;
|
||||||
private final DateUtil dateUtil;
|
private final DateUtil dateUtil;
|
||||||
private final RuffyCommands ruffyScripter;
|
private final RuffyCommands ruffyScripter;
|
||||||
private final UiInteraction uiInteraction;
|
private final UiInteraction uiInteraction;
|
||||||
|
private RxBus rxBus;
|
||||||
private final static PumpDescription pumpDescription = new PumpDescription();
|
private final BolusProgressReporter bolusProgressReporter = (state, percent, delivered) -> {
|
||||||
|
EventOverviewBolusProgress event = EventOverviewBolusProgress.INSTANCE;
|
||||||
|
switch (state) {
|
||||||
@NonNull
|
case PROGRAMMING:
|
||||||
private static final ComboPump pump = new ComboPump();
|
event.setStatus(getRh().gs(R.string.combo_programming_bolus));
|
||||||
|
break;
|
||||||
|
case DELIVERING:
|
||||||
|
event.setStatus(getRh().gs(info.nightscout.core.ui.R.string.bolus_delivering, delivered));
|
||||||
|
break;
|
||||||
|
case DELIVERED:
|
||||||
|
event.setStatus(getRh().gs(info.nightscout.core.ui.R.string.bolus_delivered_successfully, delivered));
|
||||||
|
break;
|
||||||
|
case STOPPING:
|
||||||
|
event.setStatus(getRh().gs(R.string.bolusstopping));
|
||||||
|
break;
|
||||||
|
case STOPPED:
|
||||||
|
event.setStatus(getRh().gs(R.string.bolusstopped));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
event.setPercent(percent);
|
||||||
|
rxBus.send(event);
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* This is used to determine when to pass a bolus cancel request to the scripter
|
* This is used to determine when to pass a bolus cancel request to the scripter
|
||||||
*/
|
*/
|
||||||
|
@ -112,7 +130,6 @@ public class ComboPlugin extends PumpPluginBase implements Pump, Constraints {
|
||||||
* will reset this flag.
|
* will reset this flag.
|
||||||
*/
|
*/
|
||||||
private volatile boolean cancelBolus;
|
private volatile boolean cancelBolus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is set (in {@link #checkHistory()} whenever a connection to the pump is made and
|
* This is set (in {@link #checkHistory()} whenever a connection to the pump is made and
|
||||||
* indicates if new history records on the pump have been found. This effectively blocks
|
* indicates if new history records on the pump have been found. This effectively blocks
|
||||||
|
@ -128,7 +145,6 @@ public class ComboPlugin extends PumpPluginBase implements Pump, Constraints {
|
||||||
* direction - so that adding more complexity yields little benefit.
|
* direction - so that adding more complexity yields little benefit.
|
||||||
*/
|
*/
|
||||||
private volatile boolean pumpHistoryChanged = false;
|
private volatile boolean pumpHistoryChanged = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache of the last <=2 boluses on the pump. Used to detect changes in pump history,
|
* Cache of the last <=2 boluses on the pump. Used to detect changes in pump history,
|
||||||
* requiring reading more pump history. This is read/set in {@link #checkHistory()} when changed
|
* requiring reading more pump history. This is read/set in {@link #checkHistory()} when changed
|
||||||
|
@ -136,8 +152,11 @@ public class ComboPlugin extends PumpPluginBase implements Pump, Constraints {
|
||||||
* after bolus delivery. Newest record is the first one.
|
* after bolus delivery. Newest record is the first one.
|
||||||
*/
|
*/
|
||||||
private volatile List<Bolus> recentBoluses = new ArrayList<>(0);
|
private volatile List<Bolus> recentBoluses = new ArrayList<>(0);
|
||||||
|
|
||||||
private PumpEnactResult OPERATION_NOT_SUPPORTED;
|
private PumpEnactResult OPERATION_NOT_SUPPORTED;
|
||||||
|
// Constraints interface
|
||||||
|
private long lowSuspendOnlyLoopEnforcedUntil = 0;
|
||||||
|
private long violationWarningRaisedForBolusAt = 0;
|
||||||
|
private boolean validBasalRateProfileSelectedOnPump = true;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ComboPlugin(
|
public ComboPlugin(
|
||||||
|
@ -469,29 +488,6 @@ public class ComboPlugin extends PumpPluginBase implements Pump, Constraints {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final BolusProgressReporter bolusProgressReporter = (state, percent, delivered) -> {
|
|
||||||
EventOverviewBolusProgress event = EventOverviewBolusProgress.INSTANCE;
|
|
||||||
switch (state) {
|
|
||||||
case PROGRAMMING:
|
|
||||||
event.setStatus(getRh().gs(R.string.combo_programming_bolus));
|
|
||||||
break;
|
|
||||||
case DELIVERING:
|
|
||||||
event.setStatus(getRh().gs(info.nightscout.core.ui.R.string.bolus_delivering, delivered));
|
|
||||||
break;
|
|
||||||
case DELIVERED:
|
|
||||||
event.setStatus(getRh().gs(info.nightscout.core.ui.R.string.bolus_delivered_successfully, delivered));
|
|
||||||
break;
|
|
||||||
case STOPPING:
|
|
||||||
event.setStatus(getRh().gs(R.string.bolusstopping));
|
|
||||||
break;
|
|
||||||
case STOPPED:
|
|
||||||
event.setStatus(getRh().gs(R.string.bolusstopped));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
event.setPercent(percent);
|
|
||||||
rxBus.send(event);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates Treatment records with carbs and boluses and delivers a bolus if needed
|
* Updates Treatment records with carbs and boluses and delivers a bolus if needed
|
||||||
*/
|
*/
|
||||||
|
@ -850,10 +846,6 @@ public class ComboPlugin extends PumpPluginBase implements Pump, Constraints {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private interface CommandExecution {
|
|
||||||
CommandResult execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs a command, sets an activity if provided, retries if requested and updates fields
|
* Runs a command, sets an activity if provided, retries if requested and updates fields
|
||||||
* concerned with last connection.
|
* concerned with last connection.
|
||||||
|
@ -980,7 +972,6 @@ public class ComboPlugin extends PumpPluginBase implements Pump, Constraints {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void checkBasalRate(PumpState state) {
|
private void checkBasalRate(PumpState state) {
|
||||||
if (!pump.initialized) {
|
if (!pump.initialized) {
|
||||||
// no cached profile to compare against
|
// no cached profile to compare against
|
||||||
|
@ -1386,22 +1377,17 @@ public class ComboPlugin extends PumpPluginBase implements Pump, Constraints {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constraints interface
|
|
||||||
private long lowSuspendOnlyLoopEnforcedUntil = 0;
|
|
||||||
private long violationWarningRaisedForBolusAt = 0;
|
|
||||||
private boolean validBasalRateProfileSelectedOnPump = true;
|
|
||||||
|
|
||||||
@NonNull @Override
|
@NonNull @Override
|
||||||
public Constraint<Boolean> isLoopInvocationAllowed(@NonNull Constraint<Boolean> value) {
|
public Constraint<Boolean> isLoopInvocationAllowed(@NonNull Constraint<Boolean> value) {
|
||||||
if (!validBasalRateProfileSelectedOnPump)
|
if (!validBasalRateProfileSelectedOnPump)
|
||||||
value.set(getAapsLogger(), false, getRh().gs(info.nightscout.core.ui.R.string.no_valid_basal_rate), this);
|
value.set(false, getRh().gs(info.nightscout.core.ui.R.string.no_valid_basal_rate), this);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull @Override
|
@NonNull @Override
|
||||||
public Constraint<Double> applyMaxIOBConstraints(@NonNull Constraint<Double> maxIob) {
|
public Constraint<Double> applyMaxIOBConstraints(@NonNull Constraint<Double> maxIob) {
|
||||||
if (lowSuspendOnlyLoopEnforcedUntil > System.currentTimeMillis())
|
if (lowSuspendOnlyLoopEnforcedUntil > System.currentTimeMillis())
|
||||||
maxIob.setIfSmaller(getAapsLogger(), 0d, getRh().gs(info.nightscout.core.ui.R.string.limiting_iob, 0d, getRh().gs(R.string.unsafeusage)), this);
|
maxIob.setIfSmaller(0d, getRh().gs(info.nightscout.core.ui.R.string.limiting_iob, 0d, getRh().gs(R.string.unsafeusage)), this);
|
||||||
return maxIob;
|
return maxIob;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1409,4 +1395,8 @@ public class ComboPlugin extends PumpPluginBase implements Pump, Constraints {
|
||||||
public boolean canHandleDST() {
|
public boolean canHandleDST() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private interface CommandExecution {
|
||||||
|
CommandResult execute();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ package info.nightscout.pump.combo
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import dagger.android.AndroidInjector
|
import dagger.android.AndroidInjector
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.interfaces.plugin.PluginType
|
import info.nightscout.interfaces.plugin.PluginType
|
||||||
import info.nightscout.interfaces.profile.ProfileFunction
|
import info.nightscout.interfaces.profile.ProfileFunction
|
||||||
import info.nightscout.interfaces.pump.PumpEnactResult
|
import info.nightscout.interfaces.pump.PumpEnactResult
|
||||||
|
@ -12,7 +12,6 @@ import info.nightscout.interfaces.queue.CommandQueue
|
||||||
import info.nightscout.interfaces.ui.UiInteraction
|
import info.nightscout.interfaces.ui.UiInteraction
|
||||||
import info.nightscout.pump.combo.ruffyscripter.RuffyScripter
|
import info.nightscout.pump.combo.ruffyscripter.RuffyScripter
|
||||||
import info.nightscout.pump.combo.ruffyscripter.history.Bolus
|
import info.nightscout.pump.combo.ruffyscripter.history.Bolus
|
||||||
import info.nightscout.rx.bus.RxBus
|
|
||||||
import info.nightscout.shared.interfaces.ResourceHelper
|
import info.nightscout.shared.interfaces.ResourceHelper
|
||||||
import info.nightscout.shared.sharedPreferences.SP
|
import info.nightscout.shared.sharedPreferences.SP
|
||||||
import info.nightscout.shared.utils.DateUtil
|
import info.nightscout.shared.utils.DateUtil
|
||||||
|
@ -37,6 +36,9 @@ class ComboPluginTest : TestBase() {
|
||||||
|
|
||||||
private val injector = HasAndroidInjector {
|
private val injector = HasAndroidInjector {
|
||||||
AndroidInjector {
|
AndroidInjector {
|
||||||
|
if (it is ConstraintObject<*>) {
|
||||||
|
it.aapsLogger = aapsLogger
|
||||||
|
}
|
||||||
if (it is PumpEnactResult) {
|
if (it is PumpEnactResult) {
|
||||||
it.context = context
|
it.context = context
|
||||||
}
|
}
|
||||||
|
@ -49,16 +51,15 @@ class ComboPluginTest : TestBase() {
|
||||||
fun prepareMocks() {
|
fun prepareMocks() {
|
||||||
`when`(rh.gs(info.nightscout.core.ui.R.string.no_valid_basal_rate)).thenReturn("No valid basal rate read from pump")
|
`when`(rh.gs(info.nightscout.core.ui.R.string.no_valid_basal_rate)).thenReturn("No valid basal rate read from pump")
|
||||||
`when`(context.getString(R.string.combo_pump_unsupported_operation)).thenReturn("Requested operation not supported by pump")
|
`when`(context.getString(R.string.combo_pump_unsupported_operation)).thenReturn("Requested operation not supported by pump")
|
||||||
comboPlugin = ComboPlugin(injector, aapsLogger, RxBus(aapsSchedulers, aapsLogger), rh, profileFunction, sp, commandQueue, pumpSync, dateUtil, ruffyScripter, uiInteraction)
|
comboPlugin = ComboPlugin(injector, aapsLogger, rxBus, rh, profileFunction, sp, commandQueue, pumpSync, dateUtil, ruffyScripter, uiInteraction)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun invalidBasalRateOnComboPumpShouldLimitLoopInvocation() {
|
fun invalidBasalRateOnComboPumpShouldLimitLoopInvocation() {
|
||||||
comboPlugin.setPluginEnabled(PluginType.PUMP, true)
|
comboPlugin.setPluginEnabled(PluginType.PUMP, true)
|
||||||
comboPlugin.setValidBasalRateProfileSelectedOnPump(false)
|
comboPlugin.setValidBasalRateProfileSelectedOnPump(false)
|
||||||
var c = Constraint(true)
|
val c = comboPlugin.isLoopInvocationAllowed(ConstraintObject(true, injector))
|
||||||
c = comboPlugin.isLoopInvocationAllowed(c)
|
Assertions.assertEquals("Combo: No valid basal rate read from pump", c.getReasons())
|
||||||
Assertions.assertEquals("Combo: No valid basal rate read from pump", c.getReasons(aapsLogger))
|
|
||||||
Assertions.assertEquals(false, c.value())
|
Assertions.assertEquals(false, c.value())
|
||||||
comboPlugin.setPluginEnabled(PluginType.PUMP, false)
|
comboPlugin.setPluginEnabled(PluginType.PUMP, false)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ apply from: "${project.rootDir}/core/main/jacoco_global.gradle"
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation project(':core:libraries')
|
implementation project(':core:libraries')
|
||||||
implementation project(':core:interfaces')
|
implementation project(':core:interfaces')
|
||||||
|
implementation project(':core:main')
|
||||||
implementation project(':core:ui')
|
implementation project(':core:ui')
|
||||||
implementation project(':core:utils')
|
implementation project(':core:utils')
|
||||||
implementation(project(":pump:combov2:comboctl"))
|
implementation(project(":pump:combov2:comboctl"))
|
||||||
|
|
|
@ -25,12 +25,14 @@ import info.nightscout.comboctl.parser.AlertScreenContent
|
||||||
import info.nightscout.comboctl.parser.AlertScreenException
|
import info.nightscout.comboctl.parser.AlertScreenException
|
||||||
import info.nightscout.comboctl.parser.BatteryState
|
import info.nightscout.comboctl.parser.BatteryState
|
||||||
import info.nightscout.comboctl.parser.ReservoirState
|
import info.nightscout.comboctl.parser.ReservoirState
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.core.ui.dialogs.OKDialog
|
import info.nightscout.core.ui.dialogs.OKDialog
|
||||||
import info.nightscout.core.ui.toast.ToastUtils
|
import info.nightscout.core.ui.toast.ToastUtils
|
||||||
import info.nightscout.interfaces.AndroidPermission
|
import info.nightscout.interfaces.AndroidPermission
|
||||||
import info.nightscout.interfaces.Config
|
import info.nightscout.interfaces.Config
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.Constraint
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
|
import info.nightscout.interfaces.constraints.PluginConstraints
|
||||||
import info.nightscout.interfaces.notifications.Notification
|
import info.nightscout.interfaces.notifications.Notification
|
||||||
import info.nightscout.interfaces.plugin.PluginDescription
|
import info.nightscout.interfaces.plugin.PluginDescription
|
||||||
import info.nightscout.interfaces.plugin.PluginType
|
import info.nightscout.interfaces.plugin.PluginType
|
||||||
|
@ -108,7 +110,7 @@ class ComboV2Plugin @Inject constructor (
|
||||||
commandQueue: CommandQueue,
|
commandQueue: CommandQueue,
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val rxBus: RxBus,
|
private val rxBus: RxBus,
|
||||||
private val constraintChecker: Constraints,
|
private val constraintChecker: ConstraintsChecker,
|
||||||
private val sp: SP,
|
private val sp: SP,
|
||||||
private val pumpSync: PumpSync,
|
private val pumpSync: PumpSync,
|
||||||
private val dateUtil: DateUtil,
|
private val dateUtil: DateUtil,
|
||||||
|
@ -132,7 +134,7 @@ class ComboV2Plugin @Inject constructor (
|
||||||
commandQueue
|
commandQueue
|
||||||
),
|
),
|
||||||
Pump,
|
Pump,
|
||||||
Constraints {
|
PluginConstraints {
|
||||||
|
|
||||||
// Coroutine scope and the associated job. All coroutines
|
// Coroutine scope and the associated job. All coroutines
|
||||||
// that are started in this plugin are part of this scope.
|
// that are started in this plugin are part of this scope.
|
||||||
|
@ -208,6 +210,7 @@ class ComboV2Plugin @Inject constructor (
|
||||||
// overwritten. This check is performed in checkBasalProfile().
|
// overwritten. This check is performed in checkBasalProfile().
|
||||||
// In setNewBasalProfile(), this value is changed.
|
// In setNewBasalProfile(), this value is changed.
|
||||||
private var activeBasalProfile: BasalProfile? = null
|
private var activeBasalProfile: BasalProfile? = null
|
||||||
|
|
||||||
// This is used for checking that the correct basal profile is
|
// This is used for checking that the correct basal profile is
|
||||||
// active in the Combo. If not, loop invocation is disallowed.
|
// active in the Combo. If not, loop invocation is disallowed.
|
||||||
// This is _not_ reset by disconnect(). That's on purpose; it
|
// This is _not_ reset by disconnect(). That's on purpose; it
|
||||||
|
@ -220,22 +223,28 @@ class ComboV2Plugin @Inject constructor (
|
||||||
/*** Public functions and base class & interface overrides ***/
|
/*** Public functions and base class & interface overrides ***/
|
||||||
|
|
||||||
sealed class DriverState(@Suppress("unused") val label: String) {
|
sealed class DriverState(@Suppress("unused") val label: String) {
|
||||||
|
|
||||||
// Initial state when the driver is created.
|
// Initial state when the driver is created.
|
||||||
object NotInitialized : DriverState("notInitialized")
|
data object NotInitialized : DriverState("notInitialized")
|
||||||
|
|
||||||
// Driver is disconnected from the pump, or no pump
|
// Driver is disconnected from the pump, or no pump
|
||||||
// is currently paired. In onStart() the driver state
|
// is currently paired. In onStart() the driver state
|
||||||
// changes from NotInitialized to this.
|
// changes from NotInitialized to this.
|
||||||
object Disconnected : DriverState("disconnected")
|
data object Disconnected : DriverState("disconnected")
|
||||||
|
|
||||||
// Driver is currently connecting to the pump. isBusy()
|
// Driver is currently connecting to the pump. isBusy()
|
||||||
// will return true in this state.
|
// will return true in this state.
|
||||||
object Connecting : DriverState("connecting")
|
data object Connecting : DriverState("connecting")
|
||||||
|
|
||||||
// Driver is running checks on the pump, like verifying
|
// Driver is running checks on the pump, like verifying
|
||||||
// that the basal rate is OK, checking for any bolus
|
// that the basal rate is OK, checking for any bolus
|
||||||
// and TBR activity that AAPS doesn't know about etc.
|
// and TBR activity that AAPS doesn't know about etc.
|
||||||
// isBusy() will return true in this state.
|
// isBusy() will return true in this state.
|
||||||
object CheckingPump : DriverState("checkingPump")
|
data object CheckingPump : DriverState("checkingPump")
|
||||||
|
|
||||||
// Driver is connected and ready to execute commands.
|
// Driver is connected and ready to execute commands.
|
||||||
object Ready : DriverState("ready")
|
data object Ready : DriverState("ready")
|
||||||
|
|
||||||
// Driver is connected, but pump is suspended and
|
// Driver is connected, but pump is suspended and
|
||||||
// cannot currently execute commands. This state is
|
// cannot currently execute commands. This state is
|
||||||
// special in that it technically persists even after
|
// special in that it technically persists even after
|
||||||
|
@ -252,11 +261,12 @@ class ComboV2Plugin @Inject constructor (
|
||||||
// the pump is currently suspended or not. Use
|
// the pump is currently suspended or not. Use
|
||||||
// isSuspended() instead. See the pumpIsSuspended
|
// isSuspended() instead. See the pumpIsSuspended
|
||||||
// documentation for details.
|
// documentation for details.
|
||||||
object Suspended : DriverState("suspended")
|
data object Suspended : DriverState("suspended")
|
||||||
|
|
||||||
// Driver is currently executing a command.
|
// Driver is currently executing a command.
|
||||||
// isBusy() will return true in this state.
|
// isBusy() will return true in this state.
|
||||||
class ExecutingCommand(val description: ComboCtlPump.CommandDescription) : DriverState("executingCommand")
|
class ExecutingCommand(val description: ComboCtlPump.CommandDescription) : DriverState("executingCommand")
|
||||||
object Error : DriverState("error")
|
data object Error : DriverState("error")
|
||||||
}
|
}
|
||||||
|
|
||||||
private val driverStateFlow = _driverStateFlow.asStateFlow()
|
private val driverStateFlow = _driverStateFlow.asStateFlow()
|
||||||
|
@ -264,7 +274,9 @@ class ComboV2Plugin @Inject constructor (
|
||||||
// Used by ComboV2PairingActivity to launch its own
|
// Used by ComboV2PairingActivity to launch its own
|
||||||
// custom activities that have a result.
|
// custom activities that have a result.
|
||||||
var customDiscoveryActivityStartCallback: ((intent: Intent) -> Unit)?
|
var customDiscoveryActivityStartCallback: ((intent: Intent) -> Unit)?
|
||||||
set(value) { bluetoothInterface?.customDiscoveryActivityStartCallback = value }
|
set(value) {
|
||||||
|
bluetoothInterface?.customDiscoveryActivityStartCallback = value
|
||||||
|
}
|
||||||
get() = bluetoothInterface?.customDiscoveryActivityStartCallback
|
get() = bluetoothInterface?.customDiscoveryActivityStartCallback
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -494,6 +506,7 @@ class ComboV2Plugin @Inject constructor (
|
||||||
// returning true then causes problems with AAPS' KeepAlive mechanism.
|
// returning true then causes problems with AAPS' KeepAlive mechanism.
|
||||||
DriverState.CheckingPump,
|
DriverState.CheckingPump,
|
||||||
is DriverState.ExecutingCommand -> true
|
is DriverState.ExecutingCommand -> true
|
||||||
|
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -509,6 +522,7 @@ class ComboV2Plugin @Inject constructor (
|
||||||
DriverState.Ready,
|
DriverState.Ready,
|
||||||
DriverState.Suspended,
|
DriverState.Suspended,
|
||||||
is DriverState.ExecutingCommand -> true
|
is DriverState.ExecutingCommand -> true
|
||||||
|
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,6 +530,7 @@ class ComboV2Plugin @Inject constructor (
|
||||||
when (driverStateFlow.value) {
|
when (driverStateFlow.value) {
|
||||||
DriverState.Connecting,
|
DriverState.Connecting,
|
||||||
DriverState.CheckingPump -> true
|
DriverState.CheckingPump -> true
|
||||||
|
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,6 +569,7 @@ class ComboV2Plugin @Inject constructor (
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> Unit
|
else -> Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -575,6 +591,7 @@ class ComboV2Plugin @Inject constructor (
|
||||||
unpairDueToPumpDataError()
|
unpairDueToPumpDataError()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> address
|
else -> address
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -686,6 +703,7 @@ class ComboV2Plugin @Inject constructor (
|
||||||
pumpIsSuspended = when (it.stateFlow.value) {
|
pumpIsSuspended = when (it.stateFlow.value) {
|
||||||
ComboCtlPump.State.Suspended,
|
ComboCtlPump.State.Suspended,
|
||||||
is ComboCtlPump.State.Error -> true
|
is ComboCtlPump.State.Error -> true
|
||||||
|
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -996,7 +1014,7 @@ class ComboV2Plugin @Inject constructor (
|
||||||
override fun deliverTreatment(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult {
|
override fun deliverTreatment(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult {
|
||||||
val oldInsulinAmount = detailedBolusInfo.insulin
|
val oldInsulinAmount = detailedBolusInfo.insulin
|
||||||
detailedBolusInfo.insulin = constraintChecker
|
detailedBolusInfo.insulin = constraintChecker
|
||||||
.applyBolusConstraints(Constraint(detailedBolusInfo.insulin))
|
.applyBolusConstraints(ConstraintObject(detailedBolusInfo.insulin, injector))
|
||||||
.value()
|
.value()
|
||||||
aapsLogger.debug(
|
aapsLogger.debug(
|
||||||
LTag.PUMP,
|
LTag.PUMP,
|
||||||
|
@ -1055,12 +1073,14 @@ class ComboV2Plugin @Inject constructor (
|
||||||
bolusingEvent.status = rh.gs(info.nightscout.core.ui.R.string.bolus_delivering, detailedBolusInfo.insulin)
|
bolusingEvent.status = rh.gs(info.nightscout.core.ui.R.string.bolus_delivering, detailedBolusInfo.insulin)
|
||||||
rxBus.send(bolusingEvent)
|
rxBus.send(bolusingEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicProgressStage.Finished -> {
|
BasicProgressStage.Finished -> {
|
||||||
val bolusingEvent = EventOverviewBolusProgress
|
val bolusingEvent = EventOverviewBolusProgress
|
||||||
bolusingEvent.percent = (progressReport.overallProgress * 100.0).toInt()
|
bolusingEvent.percent = (progressReport.overallProgress * 100.0).toInt()
|
||||||
bolusingEvent.status = "Bolus finished, performing post-bolus checks"
|
bolusingEvent.status = "Bolus finished, performing post-bolus checks"
|
||||||
rxBus.send(bolusingEvent)
|
rxBus.send(bolusingEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> Unit
|
else -> Unit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1193,6 +1213,7 @@ class ComboV2Plugin @Inject constructor (
|
||||||
PumpSync.TemporaryBasalType.NORMAL -> ComboCtlTbr.Type.NORMAL
|
PumpSync.TemporaryBasalType.NORMAL -> ComboCtlTbr.Type.NORMAL
|
||||||
PumpSync.TemporaryBasalType.EMULATED_PUMP_SUSPEND -> ComboCtlTbr.Type.EMULATED_COMBO_STOP
|
PumpSync.TemporaryBasalType.EMULATED_PUMP_SUSPEND -> ComboCtlTbr.Type.EMULATED_COMBO_STOP
|
||||||
PumpSync.TemporaryBasalType.SUPERBOLUS -> ComboCtlTbr.Type.SUPERBOLUS
|
PumpSync.TemporaryBasalType.SUPERBOLUS -> ComboCtlTbr.Type.SUPERBOLUS
|
||||||
|
|
||||||
PumpSync.TemporaryBasalType.PUMP_SUSPEND -> {
|
PumpSync.TemporaryBasalType.PUMP_SUSPEND -> {
|
||||||
aapsLogger.error(
|
aapsLogger.error(
|
||||||
LTag.PUMP,
|
LTag.PUMP,
|
||||||
|
@ -1224,6 +1245,7 @@ class ComboV2Plugin @Inject constructor (
|
||||||
PumpSync.TemporaryBasalType.NORMAL -> ComboCtlTbr.Type.NORMAL
|
PumpSync.TemporaryBasalType.NORMAL -> ComboCtlTbr.Type.NORMAL
|
||||||
PumpSync.TemporaryBasalType.EMULATED_PUMP_SUSPEND -> ComboCtlTbr.Type.EMULATED_COMBO_STOP
|
PumpSync.TemporaryBasalType.EMULATED_PUMP_SUSPEND -> ComboCtlTbr.Type.EMULATED_COMBO_STOP
|
||||||
PumpSync.TemporaryBasalType.SUPERBOLUS -> ComboCtlTbr.Type.SUPERBOLUS
|
PumpSync.TemporaryBasalType.SUPERBOLUS -> ComboCtlTbr.Type.SUPERBOLUS
|
||||||
|
|
||||||
PumpSync.TemporaryBasalType.PUMP_SUSPEND -> {
|
PumpSync.TemporaryBasalType.PUMP_SUSPEND -> {
|
||||||
aapsLogger.error(
|
aapsLogger.error(
|
||||||
LTag.PUMP,
|
LTag.PUMP,
|
||||||
|
@ -1277,10 +1299,13 @@ class ComboV2Plugin @Inject constructor (
|
||||||
val tbrComment = when (acquiredPump.setTbr(percentage, durationInMinutes, tbrType, force100Percent)) {
|
val tbrComment = when (acquiredPump.setTbr(percentage, durationInMinutes, tbrType, force100Percent)) {
|
||||||
ComboCtlPump.SetTbrOutcome.SET_NORMAL_TBR ->
|
ComboCtlPump.SetTbrOutcome.SET_NORMAL_TBR ->
|
||||||
rh.gs(R.string.combov2_setting_tbr_succeeded)
|
rh.gs(R.string.combov2_setting_tbr_succeeded)
|
||||||
|
|
||||||
ComboCtlPump.SetTbrOutcome.SET_EMULATED_100_TBR ->
|
ComboCtlPump.SetTbrOutcome.SET_EMULATED_100_TBR ->
|
||||||
rh.gs(R.string.combov2_set_emulated_100_tbr)
|
rh.gs(R.string.combov2_set_emulated_100_tbr)
|
||||||
|
|
||||||
ComboCtlPump.SetTbrOutcome.LETTING_EMULATED_100_TBR_FINISH ->
|
ComboCtlPump.SetTbrOutcome.LETTING_EMULATED_100_TBR_FINISH ->
|
||||||
rh.gs(R.string.combov2_letting_emulated_100_tbr_finish)
|
rh.gs(R.string.combov2_letting_emulated_100_tbr_finish)
|
||||||
|
|
||||||
ComboCtlPump.SetTbrOutcome.IGNORED_REDUNDANT_100_TBR ->
|
ComboCtlPump.SetTbrOutcome.IGNORED_REDUNDANT_100_TBR ->
|
||||||
rh.gs(R.string.combov2_ignoring_redundant_100_tbr)
|
rh.gs(R.string.combov2_ignoring_redundant_100_tbr)
|
||||||
}
|
}
|
||||||
|
@ -1407,8 +1432,10 @@ class ComboV2Plugin @Inject constructor (
|
||||||
when (val alert = lastComboAlert) {
|
when (val alert = lastComboAlert) {
|
||||||
is AlertScreenContent.Warning ->
|
is AlertScreenContent.Warning ->
|
||||||
put("WarningCode", alert.code)
|
put("WarningCode", alert.code)
|
||||||
|
|
||||||
is AlertScreenContent.Error ->
|
is AlertScreenContent.Error ->
|
||||||
put("ErrorCode", alert.code)
|
put("ErrorCode", alert.code)
|
||||||
|
|
||||||
else -> Unit
|
else -> Unit
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -1594,12 +1621,7 @@ class ComboV2Plugin @Inject constructor (
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!isAllowed) {
|
if (!isAllowed) {
|
||||||
value.set(
|
value.set(false, rh.gs(R.string.combov2_incorrect_active_basal_profile, lastActiveBasalProfileNumber), this)
|
||||||
aapsLogger,
|
|
||||||
false,
|
|
||||||
rh.gs(R.string.combov2_incorrect_active_basal_profile, lastActiveBasalProfileNumber),
|
|
||||||
this
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
aapsLogger.info(
|
aapsLogger.info(
|
||||||
|
@ -1753,7 +1775,6 @@ class ComboV2Plugin @Inject constructor (
|
||||||
// the PumpManager onPumpUnpaired callback.
|
// the PumpManager onPumpUnpaired callback.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*** User interface flows ***/
|
/*** User interface flows ***/
|
||||||
|
|
||||||
// "UI flows" are hot flows that are meant to be used for showing
|
// "UI flows" are hot flows that are meant to be used for showing
|
||||||
|
@ -1788,6 +1809,7 @@ class ComboV2Plugin @Inject constructor (
|
||||||
// establishing a BT connection, or delivering a bolus, setting
|
// establishing a BT connection, or delivering a bolus, setting
|
||||||
// a basal rate factor, reading the current pump datetime etc.
|
// a basal rate factor, reading the current pump datetime etc.
|
||||||
data class CurrentActivityInfo(val description: String, val overallProgress: Double)
|
data class CurrentActivityInfo(val description: String, val overallProgress: Double)
|
||||||
|
|
||||||
private fun noCurrentActivity() = CurrentActivityInfo("", 0.0)
|
private fun noCurrentActivity() = CurrentActivityInfo("", 0.0)
|
||||||
private var _currentActivityUIFlow = MutableStateFlow(noCurrentActivity())
|
private var _currentActivityUIFlow = MutableStateFlow(noCurrentActivity())
|
||||||
val currentActivityUIFlow = _currentActivityUIFlow.asStateFlow()
|
val currentActivityUIFlow = _currentActivityUIFlow.asStateFlow()
|
||||||
|
@ -1799,6 +1821,7 @@ class ComboV2Plugin @Inject constructor (
|
||||||
val batteryStateUIFlow = _batteryStateUIFlow.asStateFlow()
|
val batteryStateUIFlow = _batteryStateUIFlow.asStateFlow()
|
||||||
|
|
||||||
data class ReservoirLevel(val state: ReservoirState, val availableUnits: Int)
|
data class ReservoirLevel(val state: ReservoirState, val availableUnits: Int)
|
||||||
|
|
||||||
private var _reservoirLevelUIFlow = MutableStateFlow<ReservoirLevel?>(null)
|
private var _reservoirLevelUIFlow = MutableStateFlow<ReservoirLevel?>(null)
|
||||||
val reservoirLevelUIFlow = _reservoirLevelUIFlow.asStateFlow()
|
val reservoirLevelUIFlow = _reservoirLevelUIFlow.asStateFlow()
|
||||||
|
|
||||||
|
@ -1830,7 +1853,6 @@ class ComboV2Plugin @Inject constructor (
|
||||||
private var _displayFrameUIFlow = MutableSharedFlow<DisplayFrame?>(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)
|
private var _displayFrameUIFlow = MutableSharedFlow<DisplayFrame?>(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)
|
||||||
val displayFrameUIFlow = _displayFrameUIFlow.asSharedFlow()
|
val displayFrameUIFlow = _displayFrameUIFlow.asSharedFlow()
|
||||||
|
|
||||||
|
|
||||||
/*** Misc private functions ***/
|
/*** Misc private functions ***/
|
||||||
|
|
||||||
private fun setupUiFlows(acquiredPump: ComboCtlPump) {
|
private fun setupUiFlows(acquiredPump: ComboCtlPump) {
|
||||||
|
@ -1845,6 +1867,7 @@ class ComboV2Plugin @Inject constructor (
|
||||||
R.string.combov2_establishing_bt_connection,
|
R.string.combov2_establishing_bt_connection,
|
||||||
progStage.currentAttemptNr
|
progStage.currentAttemptNr
|
||||||
)
|
)
|
||||||
|
|
||||||
BasicProgressStage.PerformingConnectionHandshake -> rh.gs(R.string.combov2_pairing_performing_handshake)
|
BasicProgressStage.PerformingConnectionHandshake -> rh.gs(R.string.combov2_pairing_performing_handshake)
|
||||||
else -> ""
|
else -> ""
|
||||||
}
|
}
|
||||||
|
@ -1860,9 +1883,11 @@ class ComboV2Plugin @Inject constructor (
|
||||||
val description = when (progressReport.stage) {
|
val description = when (progressReport.stage) {
|
||||||
RTCommandProgressStage.SettingDateTimeHour,
|
RTCommandProgressStage.SettingDateTimeHour,
|
||||||
RTCommandProgressStage.SettingDateTimeMinute -> rh.gs(R.string.combov2_setting_current_pump_time)
|
RTCommandProgressStage.SettingDateTimeMinute -> rh.gs(R.string.combov2_setting_current_pump_time)
|
||||||
|
|
||||||
RTCommandProgressStage.SettingDateTimeYear,
|
RTCommandProgressStage.SettingDateTimeYear,
|
||||||
RTCommandProgressStage.SettingDateTimeMonth,
|
RTCommandProgressStage.SettingDateTimeMonth,
|
||||||
RTCommandProgressStage.SettingDateTimeDay -> rh.gs(R.string.combov2_setting_current_pump_date)
|
RTCommandProgressStage.SettingDateTimeDay -> rh.gs(R.string.combov2_setting_current_pump_date)
|
||||||
|
|
||||||
else -> ""
|
else -> ""
|
||||||
}
|
}
|
||||||
_currentActivityUIFlow.value = CurrentActivityInfo(
|
_currentActivityUIFlow.value = CurrentActivityInfo(
|
||||||
|
@ -1877,6 +1902,7 @@ class ComboV2Plugin @Inject constructor (
|
||||||
val description = when (val stage = progressReport.stage) {
|
val description = when (val stage = progressReport.stage) {
|
||||||
is RTCommandProgressStage.GettingBasalProfile ->
|
is RTCommandProgressStage.GettingBasalProfile ->
|
||||||
rh.gs(R.string.combov2_getting_basal_profile, stage.numSetFactors)
|
rh.gs(R.string.combov2_getting_basal_profile, stage.numSetFactors)
|
||||||
|
|
||||||
else -> ""
|
else -> ""
|
||||||
}
|
}
|
||||||
_currentActivityUIFlow.value = CurrentActivityInfo(
|
_currentActivityUIFlow.value = CurrentActivityInfo(
|
||||||
|
@ -1891,6 +1917,7 @@ class ComboV2Plugin @Inject constructor (
|
||||||
val description = when (val stage = progressReport.stage) {
|
val description = when (val stage = progressReport.stage) {
|
||||||
is RTCommandProgressStage.SettingBasalProfile ->
|
is RTCommandProgressStage.SettingBasalProfile ->
|
||||||
rh.gs(R.string.combov2_setting_basal_profile, stage.numSetFactors)
|
rh.gs(R.string.combov2_setting_basal_profile, stage.numSetFactors)
|
||||||
|
|
||||||
else -> ""
|
else -> ""
|
||||||
}
|
}
|
||||||
_currentActivityUIFlow.value = CurrentActivityInfo(
|
_currentActivityUIFlow.value = CurrentActivityInfo(
|
||||||
|
@ -1909,6 +1936,7 @@ class ComboV2Plugin @Inject constructor (
|
||||||
stage.deliveredImmediateAmount.cctlBolusToIU(),
|
stage.deliveredImmediateAmount.cctlBolusToIU(),
|
||||||
stage.totalImmediateAmount.cctlBolusToIU()
|
stage.totalImmediateAmount.cctlBolusToIU()
|
||||||
)
|
)
|
||||||
|
|
||||||
else -> ""
|
else -> ""
|
||||||
}
|
}
|
||||||
_currentActivityUIFlow.value = CurrentActivityInfo(
|
_currentActivityUIFlow.value = CurrentActivityInfo(
|
||||||
|
@ -2229,9 +2257,11 @@ class ComboV2Plugin @Inject constructor (
|
||||||
when (driverStateUIFlow.value) {
|
when (driverStateUIFlow.value) {
|
||||||
DriverState.Error,
|
DriverState.Error,
|
||||||
DriverState.Suspended -> false
|
DriverState.Suspended -> false
|
||||||
|
|
||||||
else -> true
|
else -> true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> true
|
else -> true
|
||||||
}
|
}
|
||||||
if (updateUIState) {
|
if (updateUIState) {
|
||||||
|
@ -2264,10 +2294,12 @@ class ComboV2Plugin @Inject constructor (
|
||||||
if (oldState != DriverState.Suspended)
|
if (oldState != DriverState.Suspended)
|
||||||
rxBus.send(EventPumpStatusChanged(EventPumpStatusChanged.Status.CONNECTED))
|
rxBus.send(EventPumpStatusChanged(EventPumpStatusChanged.Status.CONNECTED))
|
||||||
}
|
}
|
||||||
|
|
||||||
DriverState.Suspended -> {
|
DriverState.Suspended -> {
|
||||||
if (oldState != DriverState.Ready)
|
if (oldState != DriverState.Ready)
|
||||||
rxBus.send(EventPumpStatusChanged(EventPumpStatusChanged.Status.CONNECTED))
|
rxBus.send(EventPumpStatusChanged(EventPumpStatusChanged.Status.CONNECTED))
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> Unit
|
else -> Unit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2411,6 +2443,7 @@ class ComboV2Plugin @Inject constructor (
|
||||||
when (driverStateFlow.value) {
|
when (driverStateFlow.value) {
|
||||||
DriverState.NotInitialized,
|
DriverState.NotInitialized,
|
||||||
DriverState.Disconnected -> true
|
DriverState.Disconnected -> true
|
||||||
|
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,9 @@ import info.nightscout.androidaps.danaRKorean.services.DanaRKoreanExecutionServi
|
||||||
import info.nightscout.androidaps.danar.AbstractDanaRPlugin
|
import info.nightscout.androidaps.danar.AbstractDanaRPlugin
|
||||||
import info.nightscout.androidaps.danar.R
|
import info.nightscout.androidaps.danar.R
|
||||||
import info.nightscout.annotations.OpenForTesting
|
import info.nightscout.annotations.OpenForTesting
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
|
||||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||||
import info.nightscout.interfaces.profile.Profile
|
import info.nightscout.interfaces.profile.Profile
|
||||||
import info.nightscout.interfaces.pump.DetailedBolusInfo
|
import info.nightscout.interfaces.pump.DetailedBolusInfo
|
||||||
|
@ -51,7 +51,7 @@ class DanaRKoreanPlugin @Inject constructor(
|
||||||
rxBus: RxBus,
|
rxBus: RxBus,
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
rh: ResourceHelper,
|
rh: ResourceHelper,
|
||||||
constraintChecker: Constraints,
|
constraintChecker: ConstraintsChecker,
|
||||||
activePlugin: ActivePlugin,
|
activePlugin: ActivePlugin,
|
||||||
sp: SP,
|
sp: SP,
|
||||||
commandQueue: CommandQueue,
|
commandQueue: CommandQueue,
|
||||||
|
@ -147,7 +147,7 @@ class DanaRKoreanPlugin @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun deliverTreatment(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult {
|
override fun deliverTreatment(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult {
|
||||||
detailedBolusInfo.insulin = constraintChecker.applyBolusConstraints(Constraint(detailedBolusInfo.insulin)).value()
|
detailedBolusInfo.insulin = constraintChecker.applyBolusConstraints(ConstraintObject(detailedBolusInfo.insulin, injector)).value()
|
||||||
require(detailedBolusInfo.carbs > 0)
|
require(detailedBolusInfo.carbs > 0)
|
||||||
return if (detailedBolusInfo.insulin > 0) {
|
return if (detailedBolusInfo.insulin > 0) {
|
||||||
val t = EventOverviewBolusProgress.Treatment(0.0, 0, detailedBolusInfo.bolusType == DetailedBolusInfo.BolusType.SMB, detailedBolusInfo.id)
|
val t = EventOverviewBolusProgress.Treatment(0.0, 0, detailedBolusInfo.bolusType == DetailedBolusInfo.BolusType.SMB, detailedBolusInfo.id)
|
||||||
|
@ -192,7 +192,7 @@ class DanaRKoreanPlugin @Inject constructor(
|
||||||
override fun setTempBasalAbsolute(absoluteRate: Double, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: TemporaryBasalType): PumpEnactResult {
|
override fun setTempBasalAbsolute(absoluteRate: Double, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: TemporaryBasalType): PumpEnactResult {
|
||||||
// Recheck pump status if older than 30 min
|
// Recheck pump status if older than 30 min
|
||||||
//This should not be needed while using queue because connection should be done before calling this
|
//This should not be needed while using queue because connection should be done before calling this
|
||||||
val absoluteRateAfterConstraint = constraintChecker.applyBasalConstraints(Constraint(absoluteRate), profile).value()
|
val absoluteRateAfterConstraint = constraintChecker.applyBasalConstraints(ConstraintObject(absoluteRate, injector), profile).value()
|
||||||
var doTempOff = baseBasalRate - absoluteRateAfterConstraint == 0.0 && absoluteRateAfterConstraint >= 0.10
|
var doTempOff = baseBasalRate - absoluteRateAfterConstraint == 0.0 && absoluteRateAfterConstraint >= 0.10
|
||||||
val doLowTemp = absoluteRateAfterConstraint < baseBasalRate || absoluteRateAfterConstraint < 0.10
|
val doLowTemp = absoluteRateAfterConstraint < baseBasalRate || absoluteRateAfterConstraint < 0.10
|
||||||
val doHighTemp = absoluteRateAfterConstraint > baseBasalRate && !useExtendedBoluses
|
val doHighTemp = absoluteRateAfterConstraint > baseBasalRate && !useExtendedBoluses
|
||||||
|
@ -266,7 +266,7 @@ class DanaRKoreanPlugin @Inject constructor(
|
||||||
val durationInHalfHours = max(durationInMinutes / 30, 1)
|
val durationInHalfHours = max(durationInMinutes / 30, 1)
|
||||||
// We keep current basal running so need to sub current basal
|
// We keep current basal running so need to sub current basal
|
||||||
var extendedRateToSet: Double = absoluteRateAfterConstraint - baseBasalRate
|
var extendedRateToSet: Double = absoluteRateAfterConstraint - baseBasalRate
|
||||||
extendedRateToSet = constraintChecker.applyBasalConstraints(Constraint(extendedRateToSet), profile).value()
|
extendedRateToSet = constraintChecker.applyBasalConstraints(ConstraintObject(extendedRateToSet, injector), profile).value()
|
||||||
// needs to be rounded to 0.1
|
// needs to be rounded to 0.1
|
||||||
extendedRateToSet = Round.roundTo(extendedRateToSet, pumpDescription.extendedBolusStep * 2) // *2 because of half hours
|
extendedRateToSet = Round.roundTo(extendedRateToSet, pumpDescription.extendedBolusStep * 2) // *2 because of half hours
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ import info.nightscout.androidaps.danar.comm.MsgStatusBolusExtended;
|
||||||
import info.nightscout.androidaps.danar.comm.MsgStatusTempBasal;
|
import info.nightscout.androidaps.danar.comm.MsgStatusTempBasal;
|
||||||
import info.nightscout.androidaps.danar.services.AbstractDanaRExecutionService;
|
import info.nightscout.androidaps.danar.services.AbstractDanaRExecutionService;
|
||||||
import info.nightscout.interfaces.Constants;
|
import info.nightscout.interfaces.Constants;
|
||||||
import info.nightscout.interfaces.constraints.Constraints;
|
import info.nightscout.interfaces.constraints.ConstraintsChecker;
|
||||||
import info.nightscout.interfaces.notifications.Notification;
|
import info.nightscout.interfaces.notifications.Notification;
|
||||||
import info.nightscout.interfaces.profile.Profile;
|
import info.nightscout.interfaces.profile.Profile;
|
||||||
import info.nightscout.interfaces.profile.ProfileFunction;
|
import info.nightscout.interfaces.profile.ProfileFunction;
|
||||||
|
@ -62,7 +62,7 @@ public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService {
|
||||||
@Inject AAPSLogger aapsLogger;
|
@Inject AAPSLogger aapsLogger;
|
||||||
@Inject RxBus rxBus;
|
@Inject RxBus rxBus;
|
||||||
@Inject ResourceHelper rh;
|
@Inject ResourceHelper rh;
|
||||||
@Inject Constraints constraintChecker;
|
@Inject ConstraintsChecker constraintChecker;
|
||||||
@Inject DanaPump danaPump;
|
@Inject DanaPump danaPump;
|
||||||
@Inject DanaRPlugin danaRPlugin;
|
@Inject DanaRPlugin danaRPlugin;
|
||||||
@Inject DanaRKoreanPlugin danaRKoreanPlugin;
|
@Inject DanaRKoreanPlugin danaRKoreanPlugin;
|
||||||
|
@ -83,12 +83,6 @@ public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService {
|
||||||
mBinder = new LocalBinder();
|
mBinder = new LocalBinder();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class LocalBinder extends Binder {
|
|
||||||
public DanaRKoreanExecutionService getServiceInstance() {
|
|
||||||
return DanaRKoreanExecutionService.this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("MissingPermission") public void connect() {
|
@SuppressLint("MissingPermission") public void connect() {
|
||||||
if (mConnectionInProgress)
|
if (mConnectionInProgress)
|
||||||
return;
|
return;
|
||||||
|
@ -330,4 +324,10 @@ public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class LocalBinder extends Binder {
|
||||||
|
public DanaRKoreanExecutionService getServiceInstance() {
|
||||||
|
return DanaRKoreanExecutionService.this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,9 +16,9 @@ import info.nightscout.androidaps.danaRv2.services.DanaRv2ExecutionService;
|
||||||
import info.nightscout.androidaps.danar.AbstractDanaRPlugin;
|
import info.nightscout.androidaps.danar.AbstractDanaRPlugin;
|
||||||
import info.nightscout.androidaps.danar.R;
|
import info.nightscout.androidaps.danar.R;
|
||||||
import info.nightscout.annotations.OpenForTesting;
|
import info.nightscout.annotations.OpenForTesting;
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject;
|
||||||
import info.nightscout.core.utils.fabric.FabricPrivacy;
|
import info.nightscout.core.utils.fabric.FabricPrivacy;
|
||||||
import info.nightscout.interfaces.constraints.Constraint;
|
import info.nightscout.interfaces.constraints.ConstraintsChecker;
|
||||||
import info.nightscout.interfaces.constraints.Constraints;
|
|
||||||
import info.nightscout.interfaces.plugin.ActivePlugin;
|
import info.nightscout.interfaces.plugin.ActivePlugin;
|
||||||
import info.nightscout.interfaces.profile.Profile;
|
import info.nightscout.interfaces.profile.Profile;
|
||||||
import info.nightscout.interfaces.pump.DetailedBolusInfo;
|
import info.nightscout.interfaces.pump.DetailedBolusInfo;
|
||||||
|
@ -53,6 +53,19 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
|
||||||
private final DetailedBolusInfoStorage detailedBolusInfoStorage;
|
private final DetailedBolusInfoStorage detailedBolusInfoStorage;
|
||||||
private final TemporaryBasalStorage temporaryBasalStorage;
|
private final TemporaryBasalStorage temporaryBasalStorage;
|
||||||
private final FabricPrivacy fabricPrivacy;
|
private final FabricPrivacy fabricPrivacy;
|
||||||
|
private final ServiceConnection mConnection = new ServiceConnection() {
|
||||||
|
|
||||||
|
public void onServiceDisconnected(ComponentName name) {
|
||||||
|
aapsLogger.debug(LTag.PUMP, "Service is disconnected");
|
||||||
|
sExecutionService = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||||
|
aapsLogger.debug(LTag.PUMP, "Service is connected");
|
||||||
|
DanaRv2ExecutionService.LocalBinder mLocalBinder = (DanaRv2ExecutionService.LocalBinder) service;
|
||||||
|
sExecutionService = mLocalBinder.getServiceInstance();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public DanaRv2Plugin(
|
public DanaRv2Plugin(
|
||||||
|
@ -62,7 +75,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
|
||||||
RxBus rxBus,
|
RxBus rxBus,
|
||||||
Context context,
|
Context context,
|
||||||
ResourceHelper rh,
|
ResourceHelper rh,
|
||||||
Constraints constraintChecker,
|
ConstraintsChecker constraintChecker,
|
||||||
ActivePlugin activePlugin,
|
ActivePlugin activePlugin,
|
||||||
SP sp,
|
SP sp,
|
||||||
CommandQueue commandQueue,
|
CommandQueue commandQueue,
|
||||||
|
@ -111,20 +124,6 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
|
||||||
super.onStop();
|
super.onStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ServiceConnection mConnection = new ServiceConnection() {
|
|
||||||
|
|
||||||
public void onServiceDisconnected(ComponentName name) {
|
|
||||||
aapsLogger.debug(LTag.PUMP, "Service is disconnected");
|
|
||||||
sExecutionService = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
|
||||||
aapsLogger.debug(LTag.PUMP, "Service is connected");
|
|
||||||
DanaRv2ExecutionService.LocalBinder mLocalBinder = (DanaRv2ExecutionService.LocalBinder) service;
|
|
||||||
sExecutionService = mLocalBinder.getServiceInstance();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Plugin base interface
|
// Plugin base interface
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
|
@ -160,7 +159,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
|
||||||
// Pump interface
|
// Pump interface
|
||||||
@NonNull @Override
|
@NonNull @Override
|
||||||
public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) {
|
public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) {
|
||||||
detailedBolusInfo.insulin = constraintChecker.applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value();
|
detailedBolusInfo.insulin = constraintChecker.applyBolusConstraints(new ConstraintObject<>(detailedBolusInfo.insulin, getInjector())).value();
|
||||||
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) {
|
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) {
|
||||||
// v2 stores end time for bolus, we need to adjust time
|
// v2 stores end time for bolus, we need to adjust time
|
||||||
// default delivery speed is 12 sec/U
|
// default delivery speed is 12 sec/U
|
||||||
|
@ -225,7 +224,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
|
||||||
|
|
||||||
PumpEnactResult result = new PumpEnactResult(getInjector());
|
PumpEnactResult result = new PumpEnactResult(getInjector());
|
||||||
|
|
||||||
absoluteRate = constraintChecker.applyBasalConstraints(new Constraint<>(absoluteRate), profile).value();
|
absoluteRate = constraintChecker.applyBasalConstraints(new ConstraintObject<>(absoluteRate, getInjector()), profile).value();
|
||||||
|
|
||||||
boolean doTempOff = getBaseBasalRate() - absoluteRate == 0d && absoluteRate >= 0.10d;
|
boolean doTempOff = getBaseBasalRate() - absoluteRate == 0d && absoluteRate >= 0.10d;
|
||||||
final boolean doLowTemp = absoluteRate < getBaseBasalRate() || absoluteRate < 0.10d;
|
final boolean doLowTemp = absoluteRate < getBaseBasalRate() || absoluteRate < 0.10d;
|
||||||
|
@ -291,7 +290,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
|
||||||
public PumpEnactResult setTempBasalPercent(int percent, int durationInMinutes, @NonNull Profile profile, boolean enforceNew, @NonNull PumpSync.TemporaryBasalType tbrType) {
|
public PumpEnactResult setTempBasalPercent(int percent, int durationInMinutes, @NonNull Profile profile, boolean enforceNew, @NonNull PumpSync.TemporaryBasalType tbrType) {
|
||||||
DanaPump pump = danaPump;
|
DanaPump pump = danaPump;
|
||||||
PumpEnactResult result = new PumpEnactResult(getInjector());
|
PumpEnactResult result = new PumpEnactResult(getInjector());
|
||||||
percent = constraintChecker.applyBasalPercentConstraints(new Constraint<>(percent), profile).value();
|
percent = constraintChecker.applyBasalPercentConstraints(new ConstraintObject<>(percent, getInjector()), profile).value();
|
||||||
if (percent < 0) {
|
if (percent < 0) {
|
||||||
result.isTempCancel(false).enacted(false).success(false).comment(info.nightscout.core.ui.R.string.invalid_input);
|
result.isTempCancel(false).enacted(false).success(false).comment(info.nightscout.core.ui.R.string.invalid_input);
|
||||||
aapsLogger.error("setTempBasalPercent: Invalid input");
|
aapsLogger.error("setTempBasalPercent: Invalid input");
|
||||||
|
@ -352,7 +351,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
|
||||||
@NonNull @Override
|
@NonNull @Override
|
||||||
public PumpEnactResult setExtendedBolus(double insulin, int durationInMinutes) {
|
public PumpEnactResult setExtendedBolus(double insulin, int durationInMinutes) {
|
||||||
DanaPump pump = danaPump;
|
DanaPump pump = danaPump;
|
||||||
insulin = constraintChecker.applyExtendedBolusConstraints(new Constraint<>(insulin)).value();
|
insulin = constraintChecker.applyExtendedBolusConstraints(new ConstraintObject<>(insulin, getInjector())).value();
|
||||||
// needs to be rounded
|
// needs to be rounded
|
||||||
int durationInHalfHours = Math.max(durationInMinutes / 30, 1);
|
int durationInHalfHours = Math.max(durationInMinutes / 30, 1);
|
||||||
insulin = Round.INSTANCE.roundTo(insulin, getPumpDescription().getExtendedBolusStep());
|
insulin = Round.INSTANCE.roundTo(insulin, getPumpDescription().getExtendedBolusStep());
|
||||||
|
|
|
@ -7,8 +7,10 @@ import org.json.JSONObject;
|
||||||
|
|
||||||
import dagger.android.HasAndroidInjector;
|
import dagger.android.HasAndroidInjector;
|
||||||
import info.nightscout.androidaps.danar.services.AbstractDanaRExecutionService;
|
import info.nightscout.androidaps.danar.services.AbstractDanaRExecutionService;
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject;
|
||||||
import info.nightscout.interfaces.constraints.Constraint;
|
import info.nightscout.interfaces.constraints.Constraint;
|
||||||
import info.nightscout.interfaces.constraints.Constraints;
|
import info.nightscout.interfaces.constraints.ConstraintsChecker;
|
||||||
|
import info.nightscout.interfaces.constraints.PluginConstraints;
|
||||||
import info.nightscout.interfaces.notifications.Notification;
|
import info.nightscout.interfaces.notifications.Notification;
|
||||||
import info.nightscout.interfaces.plugin.ActivePlugin;
|
import info.nightscout.interfaces.plugin.ActivePlugin;
|
||||||
import info.nightscout.interfaces.plugin.OwnDatabasePlugin;
|
import info.nightscout.interfaces.plugin.OwnDatabasePlugin;
|
||||||
|
@ -46,7 +48,7 @@ import io.reactivex.rxjava3.disposables.CompositeDisposable;
|
||||||
* Created by mike on 28.01.2018.
|
* Created by mike on 28.01.2018.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public abstract class AbstractDanaRPlugin extends PumpPluginBase implements Pump, Dana, Constraints, OwnDatabasePlugin {
|
public abstract class AbstractDanaRPlugin extends PumpPluginBase implements Pump, Dana, PluginConstraints, OwnDatabasePlugin {
|
||||||
protected AbstractDanaRExecutionService sExecutionService;
|
protected AbstractDanaRExecutionService sExecutionService;
|
||||||
|
|
||||||
protected CompositeDisposable disposable = new CompositeDisposable();
|
protected CompositeDisposable disposable = new CompositeDisposable();
|
||||||
|
@ -55,7 +57,7 @@ public abstract class AbstractDanaRPlugin extends PumpPluginBase implements Pump
|
||||||
|
|
||||||
protected PumpDescription pumpDescription = new PumpDescription();
|
protected PumpDescription pumpDescription = new PumpDescription();
|
||||||
protected DanaPump danaPump;
|
protected DanaPump danaPump;
|
||||||
protected Constraints constraintChecker;
|
protected ConstraintsChecker constraintChecker;
|
||||||
protected RxBus rxBus;
|
protected RxBus rxBus;
|
||||||
protected ActivePlugin activePlugin;
|
protected ActivePlugin activePlugin;
|
||||||
protected SP sp;
|
protected SP sp;
|
||||||
|
@ -65,11 +67,12 @@ public abstract class AbstractDanaRPlugin extends PumpPluginBase implements Pump
|
||||||
protected UiInteraction uiInteraction;
|
protected UiInteraction uiInteraction;
|
||||||
protected DanaHistoryDatabase danaHistoryDatabase;
|
protected DanaHistoryDatabase danaHistoryDatabase;
|
||||||
protected DecimalFormatter decimalFormatter;
|
protected DecimalFormatter decimalFormatter;
|
||||||
|
|
||||||
protected AbstractDanaRPlugin(
|
protected AbstractDanaRPlugin(
|
||||||
HasAndroidInjector injector,
|
HasAndroidInjector injector,
|
||||||
DanaPump danaPump,
|
DanaPump danaPump,
|
||||||
ResourceHelper rh,
|
ResourceHelper rh,
|
||||||
Constraints constraintChecker,
|
ConstraintsChecker constraintChecker,
|
||||||
AAPSLogger aapsLogger,
|
AAPSLogger aapsLogger,
|
||||||
AapsSchedulers aapsSchedulers,
|
AapsSchedulers aapsSchedulers,
|
||||||
CommandQueue commandQueue,
|
CommandQueue commandQueue,
|
||||||
|
@ -223,7 +226,7 @@ public abstract class AbstractDanaRPlugin extends PumpPluginBase implements Pump
|
||||||
@NonNull @Override
|
@NonNull @Override
|
||||||
public PumpEnactResult setTempBasalPercent(int percent, int durationInMinutes, @NonNull Profile profile, boolean enforceNew, @NonNull PumpSync.TemporaryBasalType tbrType) {
|
public PumpEnactResult setTempBasalPercent(int percent, int durationInMinutes, @NonNull Profile profile, boolean enforceNew, @NonNull PumpSync.TemporaryBasalType tbrType) {
|
||||||
PumpEnactResult result = new PumpEnactResult(getInjector());
|
PumpEnactResult result = new PumpEnactResult(getInjector());
|
||||||
percent = constraintChecker.applyBasalPercentConstraints(new Constraint<>(percent), profile).value();
|
percent = constraintChecker.applyBasalPercentConstraints(new ConstraintObject<>(percent, getInjector()), profile).value();
|
||||||
if (percent < 0) {
|
if (percent < 0) {
|
||||||
result.isTempCancel(false).enacted(false).success(false).comment(info.nightscout.core.ui.R.string.invalid_input);
|
result.isTempCancel(false).enacted(false).success(false).comment(info.nightscout.core.ui.R.string.invalid_input);
|
||||||
getAapsLogger().error("setTempBasalPercent: Invalid input");
|
getAapsLogger().error("setTempBasalPercent: Invalid input");
|
||||||
|
@ -270,7 +273,7 @@ public abstract class AbstractDanaRPlugin extends PumpPluginBase implements Pump
|
||||||
|
|
||||||
@NonNull @Override
|
@NonNull @Override
|
||||||
public PumpEnactResult setExtendedBolus(double insulin, int durationInMinutes) {
|
public PumpEnactResult setExtendedBolus(double insulin, int durationInMinutes) {
|
||||||
insulin = constraintChecker.applyExtendedBolusConstraints(new Constraint<>(insulin)).value();
|
insulin = constraintChecker.applyExtendedBolusConstraints(new ConstraintObject<>(insulin, getInjector())).value();
|
||||||
// needs to be rounded
|
// needs to be rounded
|
||||||
int durationInHalfHours = Math.max(durationInMinutes / 30, 1);
|
int durationInHalfHours = Math.max(durationInMinutes / 30, 1);
|
||||||
insulin = Round.INSTANCE.roundTo(insulin, getPumpDescription().getExtendedBolusStep());
|
insulin = Round.INSTANCE.roundTo(insulin, getPumpDescription().getExtendedBolusStep());
|
||||||
|
@ -462,21 +465,21 @@ public abstract class AbstractDanaRPlugin extends PumpPluginBase implements Pump
|
||||||
|
|
||||||
@NonNull @Override
|
@NonNull @Override
|
||||||
public Constraint<Double> applyBasalConstraints(Constraint<Double> absoluteRate, @NonNull Profile profile) {
|
public Constraint<Double> applyBasalConstraints(Constraint<Double> absoluteRate, @NonNull Profile profile) {
|
||||||
absoluteRate.setIfSmaller(getAapsLogger(), danaPump.getMaxBasal(), getRh().gs(info.nightscout.core.ui.R.string.limitingbasalratio, danaPump.getMaxBasal(), getRh().gs(info.nightscout.core.ui.R.string.pumplimit)), this);
|
absoluteRate.setIfSmaller(danaPump.getMaxBasal(), getRh().gs(info.nightscout.core.ui.R.string.limitingbasalratio, danaPump.getMaxBasal(), getRh().gs(info.nightscout.core.ui.R.string.pumplimit)), this);
|
||||||
return absoluteRate;
|
return absoluteRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull @Override
|
@NonNull @Override
|
||||||
public Constraint<Integer> applyBasalPercentConstraints(Constraint<Integer> percentRate, @NonNull Profile profile) {
|
public Constraint<Integer> applyBasalPercentConstraints(Constraint<Integer> percentRate, @NonNull Profile profile) {
|
||||||
percentRate.setIfGreater(getAapsLogger(), 0, getRh().gs(info.nightscout.core.ui.R.string.limitingpercentrate, 0, getRh().gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), this);
|
percentRate.setIfGreater(0, getRh().gs(info.nightscout.core.ui.R.string.limitingpercentrate, 0, getRh().gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), this);
|
||||||
percentRate.setIfSmaller(getAapsLogger(), getPumpDescription().getMaxTempPercent(), getRh().gs(info.nightscout.core.ui.R.string.limitingpercentrate, getPumpDescription().getMaxTempPercent(), getRh().gs(info.nightscout.core.ui.R.string.pumplimit)), this);
|
percentRate.setIfSmaller(getPumpDescription().getMaxTempPercent(), getRh().gs(info.nightscout.core.ui.R.string.limitingpercentrate, getPumpDescription().getMaxTempPercent(), getRh().gs(info.nightscout.core.ui.R.string.pumplimit)), this);
|
||||||
|
|
||||||
return percentRate;
|
return percentRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull @Override
|
@NonNull @Override
|
||||||
public Constraint<Double> applyBolusConstraints(Constraint<Double> insulin) {
|
public Constraint<Double> applyBolusConstraints(Constraint<Double> insulin) {
|
||||||
insulin.setIfSmaller(getAapsLogger(), danaPump.getMaxBolus(), getRh().gs(info.nightscout.core.ui.R.string.limitingbolus, danaPump.getMaxBolus(), getRh().gs(info.nightscout.core.ui.R.string.pumplimit)), this);
|
insulin.setIfSmaller(danaPump.getMaxBolus(), getRh().gs(info.nightscout.core.ui.R.string.limitingbolus, danaPump.getMaxBolus(), getRh().gs(info.nightscout.core.ui.R.string.pumplimit)), this);
|
||||||
return insulin;
|
return insulin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,9 @@ import javax.inject.Singleton;
|
||||||
import dagger.android.HasAndroidInjector;
|
import dagger.android.HasAndroidInjector;
|
||||||
import info.nightscout.androidaps.danar.services.DanaRExecutionService;
|
import info.nightscout.androidaps.danar.services.DanaRExecutionService;
|
||||||
import info.nightscout.annotations.OpenForTesting;
|
import info.nightscout.annotations.OpenForTesting;
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject;
|
||||||
import info.nightscout.core.utils.fabric.FabricPrivacy;
|
import info.nightscout.core.utils.fabric.FabricPrivacy;
|
||||||
import info.nightscout.interfaces.constraints.Constraint;
|
import info.nightscout.interfaces.constraints.ConstraintsChecker;
|
||||||
import info.nightscout.interfaces.constraints.Constraints;
|
|
||||||
import info.nightscout.interfaces.plugin.ActivePlugin;
|
import info.nightscout.interfaces.plugin.ActivePlugin;
|
||||||
import info.nightscout.interfaces.profile.Profile;
|
import info.nightscout.interfaces.profile.Profile;
|
||||||
import info.nightscout.interfaces.pump.DetailedBolusInfo;
|
import info.nightscout.interfaces.pump.DetailedBolusInfo;
|
||||||
|
@ -46,8 +46,20 @@ public class DanaRPlugin extends AbstractDanaRPlugin {
|
||||||
private final AAPSLogger aapsLogger;
|
private final AAPSLogger aapsLogger;
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final ResourceHelper rh;
|
private final ResourceHelper rh;
|
||||||
private final Constraints constraints;
|
|
||||||
private final FabricPrivacy fabricPrivacy;
|
private final FabricPrivacy fabricPrivacy;
|
||||||
|
private final ServiceConnection mConnection = new ServiceConnection() {
|
||||||
|
|
||||||
|
public void onServiceDisconnected(ComponentName name) {
|
||||||
|
aapsLogger.debug(LTag.PUMP, "Service is disconnected");
|
||||||
|
sExecutionService = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||||
|
aapsLogger.debug(LTag.PUMP, "Service is connected");
|
||||||
|
DanaRExecutionService.LocalBinder mLocalBinder = (DanaRExecutionService.LocalBinder) service;
|
||||||
|
sExecutionService = mLocalBinder.getServiceInstance();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public DanaRPlugin(
|
public DanaRPlugin(
|
||||||
|
@ -57,7 +69,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin {
|
||||||
RxBus rxBus,
|
RxBus rxBus,
|
||||||
Context context,
|
Context context,
|
||||||
ResourceHelper rh,
|
ResourceHelper rh,
|
||||||
Constraints constraints,
|
ConstraintsChecker constraintsChecker,
|
||||||
ActivePlugin activePlugin,
|
ActivePlugin activePlugin,
|
||||||
SP sp,
|
SP sp,
|
||||||
CommandQueue commandQueue,
|
CommandQueue commandQueue,
|
||||||
|
@ -69,11 +81,10 @@ public class DanaRPlugin extends AbstractDanaRPlugin {
|
||||||
DanaHistoryDatabase danaHistoryDatabase,
|
DanaHistoryDatabase danaHistoryDatabase,
|
||||||
DecimalFormatter decimalFormatter
|
DecimalFormatter decimalFormatter
|
||||||
) {
|
) {
|
||||||
super(injector, danaPump, rh, constraints, aapsLogger, aapsSchedulers, commandQueue, rxBus, activePlugin, sp, dateUtil, pumpSync, uiInteraction, danaHistoryDatabase, decimalFormatter);
|
super(injector, danaPump, rh, constraintsChecker, aapsLogger, aapsSchedulers, commandQueue, rxBus, activePlugin, sp, dateUtil, pumpSync, uiInteraction, danaHistoryDatabase, decimalFormatter);
|
||||||
this.aapsLogger = aapsLogger;
|
this.aapsLogger = aapsLogger;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.rh = rh;
|
this.rh = rh;
|
||||||
this.constraints = constraints;
|
|
||||||
this.fabricPrivacy = fabricPrivacy;
|
this.fabricPrivacy = fabricPrivacy;
|
||||||
|
|
||||||
useExtendedBoluses = sp.getBoolean(info.nightscout.core.utils.R.string.key_danar_useextended, false);
|
useExtendedBoluses = sp.getBoolean(info.nightscout.core.utils.R.string.key_danar_useextended, false);
|
||||||
|
@ -114,20 +125,6 @@ public class DanaRPlugin extends AbstractDanaRPlugin {
|
||||||
super.onStop();
|
super.onStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ServiceConnection mConnection = new ServiceConnection() {
|
|
||||||
|
|
||||||
public void onServiceDisconnected(ComponentName name) {
|
|
||||||
aapsLogger.debug(LTag.PUMP, "Service is disconnected");
|
|
||||||
sExecutionService = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
|
||||||
aapsLogger.debug(LTag.PUMP, "Service is connected");
|
|
||||||
DanaRExecutionService.LocalBinder mLocalBinder = (DanaRExecutionService.LocalBinder) service;
|
|
||||||
sExecutionService = mLocalBinder.getServiceInstance();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Plugin base interface
|
// Plugin base interface
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
|
@ -163,7 +160,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin {
|
||||||
|
|
||||||
@NonNull @Override
|
@NonNull @Override
|
||||||
public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) {
|
public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) {
|
||||||
detailedBolusInfo.insulin = constraints.applyBolusConstraints(new Constraint<>(detailedBolusInfo.insulin)).value();
|
detailedBolusInfo.insulin = constraintChecker.applyBolusConstraints(new ConstraintObject<>(detailedBolusInfo.insulin, getInjector())).value();
|
||||||
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) {
|
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) {
|
||||||
EventOverviewBolusProgress.Treatment t = new EventOverviewBolusProgress.Treatment(0, 0, detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB, detailedBolusInfo.getId());
|
EventOverviewBolusProgress.Treatment t = new EventOverviewBolusProgress.Treatment(0, 0, detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB, detailedBolusInfo.getId());
|
||||||
boolean connectionOK = false;
|
boolean connectionOK = false;
|
||||||
|
@ -210,7 +207,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin {
|
||||||
//This should not be needed while using queue because connection should be done before calling this
|
//This should not be needed while using queue because connection should be done before calling this
|
||||||
PumpEnactResult result = new PumpEnactResult(getInjector());
|
PumpEnactResult result = new PumpEnactResult(getInjector());
|
||||||
|
|
||||||
absoluteRate = constraints.applyBasalConstraints(new Constraint<>(absoluteRate), profile).value();
|
absoluteRate = constraintChecker.applyBasalConstraints(new ConstraintObject<>(absoluteRate, getInjector()), profile).value();
|
||||||
|
|
||||||
boolean doTempOff = getBaseBasalRate() - absoluteRate == 0d && absoluteRate >= 0.10d;
|
boolean doTempOff = getBaseBasalRate() - absoluteRate == 0d && absoluteRate >= 0.10d;
|
||||||
final boolean doLowTemp = absoluteRate < getBaseBasalRate() || absoluteRate < 0.10d;
|
final boolean doLowTemp = absoluteRate < getBaseBasalRate() || absoluteRate < 0.10d;
|
||||||
|
@ -289,7 +286,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin {
|
||||||
int durationInHalfHours = Math.max(durationInMinutes / 30, 1);
|
int durationInHalfHours = Math.max(durationInMinutes / 30, 1);
|
||||||
// We keep current basal running so need to sub current basal
|
// We keep current basal running so need to sub current basal
|
||||||
double extendedRateToSet = absoluteRate - getBaseBasalRate();
|
double extendedRateToSet = absoluteRate - getBaseBasalRate();
|
||||||
extendedRateToSet = constraints.applyBasalConstraints(new Constraint<>(extendedRateToSet), profile).value();
|
extendedRateToSet = constraintChecker.applyBasalConstraints(new ConstraintObject<>(extendedRateToSet, getInjector()), profile).value();
|
||||||
// needs to be rounded to 0.1
|
// needs to be rounded to 0.1
|
||||||
extendedRateToSet = Round.INSTANCE.roundTo(extendedRateToSet, pumpDescription.getExtendedBolusStep() * 2); // *2 because of half hours
|
extendedRateToSet = Round.INSTANCE.roundTo(extendedRateToSet, pumpDescription.getExtendedBolusStep() * 2); // *2 because of half hours
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import info.nightscout.androidaps.danar.DanaRPlugin
|
||||||
import info.nightscout.androidaps.danar.comm.MessageOriginalNames.getName
|
import info.nightscout.androidaps.danar.comm.MessageOriginalNames.getName
|
||||||
import info.nightscout.androidaps.utils.CRC.getCrc16
|
import info.nightscout.androidaps.utils.CRC.getCrc16
|
||||||
import info.nightscout.interfaces.ConfigBuilder
|
import info.nightscout.interfaces.ConfigBuilder
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||||
import info.nightscout.interfaces.pump.DetailedBolusInfoStorage
|
import info.nightscout.interfaces.pump.DetailedBolusInfoStorage
|
||||||
import info.nightscout.interfaces.pump.PumpSync
|
import info.nightscout.interfaces.pump.PumpSync
|
||||||
|
@ -48,7 +48,7 @@ open class MessageBase(injector: HasAndroidInjector) {
|
||||||
@Inject lateinit var commandQueue: CommandQueue
|
@Inject lateinit var commandQueue: CommandQueue
|
||||||
@Inject lateinit var detailedBolusInfoStorage: DetailedBolusInfoStorage
|
@Inject lateinit var detailedBolusInfoStorage: DetailedBolusInfoStorage
|
||||||
@Inject lateinit var temporaryBasalStorage: TemporaryBasalStorage
|
@Inject lateinit var temporaryBasalStorage: TemporaryBasalStorage
|
||||||
@Inject lateinit var constraintChecker: Constraints
|
@Inject lateinit var constraintChecker: ConstraintsChecker
|
||||||
@Inject lateinit var pumpSync: PumpSync
|
@Inject lateinit var pumpSync: PumpSync
|
||||||
@Inject lateinit var danaHistoryRecordDao: DanaHistoryRecordDao
|
@Inject lateinit var danaHistoryRecordDao: DanaHistoryRecordDao
|
||||||
@Inject lateinit var uiInteraction: UiInteraction
|
@Inject lateinit var uiInteraction: UiInteraction
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
package info.nightscout.androidaps.danar.comm
|
package info.nightscout.androidaps.danar.comm
|
||||||
|
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.rx.logging.LTag
|
import info.nightscout.rx.logging.LTag
|
||||||
|
|
||||||
|
|
||||||
class MsgBolusStart(
|
class MsgBolusStart(
|
||||||
injector: HasAndroidInjector,
|
injector: HasAndroidInjector,
|
||||||
private var amount: Double
|
private var amount: Double
|
||||||
|
@ -13,7 +12,7 @@ class MsgBolusStart(
|
||||||
init {
|
init {
|
||||||
setCommand(0x0102)
|
setCommand(0x0102)
|
||||||
// HARDCODED LIMIT
|
// HARDCODED LIMIT
|
||||||
amount = constraintChecker.applyBolusConstraints(Constraint(amount)).value()
|
amount = constraintChecker.applyBolusConstraints(ConstraintObject(amount, injector)).value()
|
||||||
addParamInt((amount * 100).toInt())
|
addParamInt((amount * 100).toInt())
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "Bolus start : $amount")
|
aapsLogger.debug(LTag.PUMPBTCOMM, "Bolus start : $amount")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
package info.nightscout.androidaps.danar.comm
|
package info.nightscout.androidaps.danar.comm
|
||||||
|
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.rx.logging.LTag
|
import info.nightscout.rx.logging.LTag
|
||||||
|
|
||||||
|
|
||||||
class MsgBolusStartWithSpeed(
|
class MsgBolusStartWithSpeed(
|
||||||
injector: HasAndroidInjector,
|
injector: HasAndroidInjector,
|
||||||
private var amount: Double,
|
private var amount: Double,
|
||||||
|
@ -14,7 +13,7 @@ class MsgBolusStartWithSpeed(
|
||||||
init {
|
init {
|
||||||
setCommand(0x0104)
|
setCommand(0x0104)
|
||||||
// HARDCODED LIMIT
|
// HARDCODED LIMIT
|
||||||
amount = constraintChecker.applyBolusConstraints(Constraint(amount)).value()
|
amount = constraintChecker.applyBolusConstraints(ConstraintObject(amount, injector)).value()
|
||||||
addParamInt((amount * 100).toInt())
|
addParamInt((amount * 100).toInt())
|
||||||
addParamByte(speed.toByte())
|
addParamByte(speed.toByte())
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "Bolus start : $amount speed: $speed")
|
aapsLogger.debug(LTag.PUMPBTCOMM, "Bolus start : $amount speed: $speed")
|
||||||
|
@ -24,10 +23,10 @@ class MsgBolusStartWithSpeed(
|
||||||
val errorCode = intFromBuff(bytes, 0, 1)
|
val errorCode = intFromBuff(bytes, 0, 1)
|
||||||
if (errorCode != 2) {
|
if (errorCode != 2) {
|
||||||
failed = true
|
failed = true
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "Messsage response: $errorCode FAILED!!")
|
aapsLogger.debug(LTag.PUMPBTCOMM, "Message response: $errorCode FAILED!!")
|
||||||
} else {
|
} else {
|
||||||
failed = false
|
failed = false
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "Messsage response: $errorCode OK")
|
aapsLogger.debug(LTag.PUMPBTCOMM, "Message response: $errorCode OK")
|
||||||
}
|
}
|
||||||
danaPump.bolusStartErrorCode = errorCode
|
danaPump.bolusStartErrorCode = errorCode
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
package info.nightscout.androidaps.danar.comm
|
package info.nightscout.androidaps.danar.comm
|
||||||
|
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.rx.logging.LTag
|
import info.nightscout.rx.logging.LTag
|
||||||
|
|
||||||
|
|
||||||
class MsgSetExtendedBolusStart(
|
class MsgSetExtendedBolusStart(
|
||||||
injector: HasAndroidInjector,
|
injector: HasAndroidInjector,
|
||||||
private var amount: Double,
|
private var amount: Double,
|
||||||
private var halfhours: Byte
|
private var halfHours: Byte
|
||||||
|
|
||||||
) : MessageBase(injector) {
|
) : MessageBase(injector) {
|
||||||
|
|
||||||
|
@ -16,12 +15,12 @@ class MsgSetExtendedBolusStart(
|
||||||
setCommand(0x0407)
|
setCommand(0x0407)
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "New message")
|
aapsLogger.debug(LTag.PUMPBTCOMM, "New message")
|
||||||
// HARDCODED LIMITS
|
// HARDCODED LIMITS
|
||||||
if (halfhours < 1) halfhours = 1
|
if (halfHours < 1) halfHours = 1
|
||||||
if (halfhours > 16) halfhours = 16
|
if (halfHours > 16) halfHours = 16
|
||||||
amount = constraintChecker.applyBolusConstraints(Constraint(amount)).value()
|
amount = constraintChecker.applyBolusConstraints(ConstraintObject(amount, injector)).value()
|
||||||
addParamInt((amount * 100).toInt())
|
addParamInt((amount * 100).toInt())
|
||||||
addParamByte(halfhours)
|
addParamByte(halfHours)
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "Set extended bolus start: " + (amount * 100).toInt() / 100.0 + "U halfhours: " + halfhours.toInt())
|
aapsLogger.debug(LTag.PUMPBTCOMM, "Set extended bolus start: " + (amount * 100).toInt() / 100.0 + "U halfHours: " + halfHours.toInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleMessage(bytes: ByteArray) {
|
override fun handleMessage(bytes: ByteArray) {
|
||||||
|
|
|
@ -3,9 +3,8 @@ package info.nightscout.pump.danaR
|
||||||
import dagger.android.AndroidInjector
|
import dagger.android.AndroidInjector
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.danar.DanaRPlugin
|
import info.nightscout.androidaps.danar.DanaRPlugin
|
||||||
import info.nightscout.interfaces.Constants
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
|
||||||
import info.nightscout.interfaces.plugin.PluginType
|
import info.nightscout.interfaces.plugin.PluginType
|
||||||
import info.nightscout.interfaces.profile.Instantiator
|
import info.nightscout.interfaces.profile.Instantiator
|
||||||
import info.nightscout.interfaces.pump.PumpSync
|
import info.nightscout.interfaces.pump.PumpSync
|
||||||
|
@ -22,7 +21,7 @@ import org.mockito.Mockito.`when`
|
||||||
|
|
||||||
class DanaRPluginTest : TestBaseWithProfile() {
|
class DanaRPluginTest : TestBaseWithProfile() {
|
||||||
|
|
||||||
@Mock lateinit var constraintChecker: Constraints
|
@Mock lateinit var constraintChecker: ConstraintsChecker
|
||||||
@Mock lateinit var commandQueue: CommandQueue
|
@Mock lateinit var commandQueue: CommandQueue
|
||||||
@Mock lateinit var pumpSync: PumpSync
|
@Mock lateinit var pumpSync: PumpSync
|
||||||
@Mock lateinit var instantiator: Instantiator
|
@Mock lateinit var instantiator: Instantiator
|
||||||
|
@ -34,7 +33,11 @@ class DanaRPluginTest : TestBaseWithProfile() {
|
||||||
private lateinit var danaRPlugin: DanaRPlugin
|
private lateinit var danaRPlugin: DanaRPlugin
|
||||||
|
|
||||||
val injector = HasAndroidInjector {
|
val injector = HasAndroidInjector {
|
||||||
AndroidInjector { }
|
AndroidInjector {
|
||||||
|
if (it is ConstraintObject<*>) {
|
||||||
|
it.aapsLogger = aapsLogger
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
|
@ -57,11 +60,11 @@ class DanaRPluginTest : TestBaseWithProfile() {
|
||||||
danaRPlugin.setPluginEnabled(PluginType.PUMP, true)
|
danaRPlugin.setPluginEnabled(PluginType.PUMP, true)
|
||||||
danaRPlugin.setPluginEnabled(PluginType.PUMP, true)
|
danaRPlugin.setPluginEnabled(PluginType.PUMP, true)
|
||||||
danaPump.maxBasal = 0.8
|
danaPump.maxBasal = 0.8
|
||||||
val c = Constraint(Constants.REALLYHIGHBASALRATE)
|
val c = ConstraintObject(Double.MAX_VALUE, injector)
|
||||||
danaRPlugin.applyBasalConstraints(c, validProfile)
|
danaRPlugin.applyBasalConstraints(c, validProfile)
|
||||||
Assertions.assertEquals(0.8, c.value(), 0.01)
|
Assertions.assertEquals(0.8, c.value(), 0.01)
|
||||||
Assertions.assertEquals("DanaR: Limiting max basal rate to 0.80 U/h because of pump limit", c.getReasons(aapsLogger))
|
Assertions.assertEquals("DanaR: Limiting max basal rate to 0.80 U/h because of pump limit", c.getReasons())
|
||||||
Assertions.assertEquals("DanaR: Limiting max basal rate to 0.80 U/h because of pump limit", c.getMostLimitedReasons(aapsLogger))
|
Assertions.assertEquals("DanaR: Limiting max basal rate to 0.80 U/h because of pump limit", c.getMostLimitedReasons())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test @Throws(Exception::class)
|
@Test @Throws(Exception::class)
|
||||||
|
@ -69,10 +72,10 @@ class DanaRPluginTest : TestBaseWithProfile() {
|
||||||
danaRPlugin.setPluginEnabled(PluginType.PUMP, true)
|
danaRPlugin.setPluginEnabled(PluginType.PUMP, true)
|
||||||
danaRPlugin.setPluginEnabled(PluginType.PUMP, true)
|
danaRPlugin.setPluginEnabled(PluginType.PUMP, true)
|
||||||
danaPump.maxBasal = 0.8
|
danaPump.maxBasal = 0.8
|
||||||
val c = Constraint(Constants.REALLYHIGHPERCENTBASALRATE)
|
val c = ConstraintObject(Int.MAX_VALUE, injector)
|
||||||
danaRPlugin.applyBasalPercentConstraints(c, validProfile)
|
danaRPlugin.applyBasalPercentConstraints(c, validProfile)
|
||||||
Assertions.assertEquals(200, c.value())
|
Assertions.assertEquals(200, c.value())
|
||||||
Assertions.assertEquals("DanaR: Limiting max percent rate to 200% because of pump limit", c.getReasons(aapsLogger))
|
Assertions.assertEquals("DanaR: Limiting max percent rate to 200% because of pump limit", c.getReasons())
|
||||||
Assertions.assertEquals("DanaR: Limiting max percent rate to 200% because of pump limit", c.getMostLimitedReasons(aapsLogger))
|
Assertions.assertEquals("DanaR: Limiting max percent rate to 200% because of pump limit", c.getMostLimitedReasons())
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,8 +6,9 @@ import info.nightscout.androidaps.danaRKorean.DanaRKoreanPlugin
|
||||||
import info.nightscout.androidaps.danaRv2.DanaRv2Plugin
|
import info.nightscout.androidaps.danaRv2.DanaRv2Plugin
|
||||||
import info.nightscout.androidaps.danar.DanaRPlugin
|
import info.nightscout.androidaps.danar.DanaRPlugin
|
||||||
import info.nightscout.androidaps.danar.comm.MessageBase
|
import info.nightscout.androidaps.danar.comm.MessageBase
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.interfaces.ConfigBuilder
|
import info.nightscout.interfaces.ConfigBuilder
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.profile.Instantiator
|
import info.nightscout.interfaces.profile.Instantiator
|
||||||
import info.nightscout.interfaces.pump.DetailedBolusInfoStorage
|
import info.nightscout.interfaces.pump.DetailedBolusInfoStorage
|
||||||
import info.nightscout.interfaces.pump.PumpSync
|
import info.nightscout.interfaces.pump.PumpSync
|
||||||
|
@ -15,7 +16,6 @@ import info.nightscout.interfaces.queue.CommandQueue
|
||||||
import info.nightscout.interfaces.ui.UiInteraction
|
import info.nightscout.interfaces.ui.UiInteraction
|
||||||
import info.nightscout.pump.dana.DanaPump
|
import info.nightscout.pump.dana.DanaPump
|
||||||
import info.nightscout.pump.dana.database.DanaHistoryRecordDao
|
import info.nightscout.pump.dana.database.DanaHistoryRecordDao
|
||||||
import info.nightscout.rx.bus.RxBus
|
|
||||||
import info.nightscout.sharedtests.TestBaseWithProfile
|
import info.nightscout.sharedtests.TestBaseWithProfile
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.mockito.ArgumentMatchers
|
import org.mockito.ArgumentMatchers
|
||||||
|
@ -32,7 +32,7 @@ open class DanaRTestBase : TestBaseWithProfile() {
|
||||||
@Mock lateinit var configBuilder: ConfigBuilder
|
@Mock lateinit var configBuilder: ConfigBuilder
|
||||||
@Mock lateinit var commandQueue: CommandQueue
|
@Mock lateinit var commandQueue: CommandQueue
|
||||||
@Mock lateinit var detailedBolusInfoStorage: DetailedBolusInfoStorage
|
@Mock lateinit var detailedBolusInfoStorage: DetailedBolusInfoStorage
|
||||||
@Mock lateinit var constraintChecker: Constraints
|
@Mock lateinit var constraintChecker: ConstraintsChecker
|
||||||
@Mock lateinit var pumpSync: PumpSync
|
@Mock lateinit var pumpSync: PumpSync
|
||||||
@Mock lateinit var danaHistoryRecordDao: DanaHistoryRecordDao
|
@Mock lateinit var danaHistoryRecordDao: DanaHistoryRecordDao
|
||||||
@Mock lateinit var instantiator: Instantiator
|
@Mock lateinit var instantiator: Instantiator
|
||||||
|
@ -50,6 +50,9 @@ open class DanaRTestBase : TestBaseWithProfile() {
|
||||||
|
|
||||||
val injector = HasAndroidInjector {
|
val injector = HasAndroidInjector {
|
||||||
AndroidInjector {
|
AndroidInjector {
|
||||||
|
if (it is ConstraintObject<*>) {
|
||||||
|
it.aapsLogger = aapsLogger
|
||||||
|
}
|
||||||
if (it is MessageBase) {
|
if (it is MessageBase) {
|
||||||
it.aapsLogger = aapsLogger
|
it.aapsLogger = aapsLogger
|
||||||
it.dateUtil = dateUtil
|
it.dateUtil = dateUtil
|
||||||
|
@ -57,7 +60,7 @@ open class DanaRTestBase : TestBaseWithProfile() {
|
||||||
it.danaRPlugin = danaRPlugin
|
it.danaRPlugin = danaRPlugin
|
||||||
it.danaRKoreanPlugin = danaRKoreanPlugin
|
it.danaRKoreanPlugin = danaRKoreanPlugin
|
||||||
it.danaRv2Plugin = danaRv2Plugin
|
it.danaRv2Plugin = danaRv2Plugin
|
||||||
it.rxBus = RxBus(aapsSchedulers, aapsLogger)
|
it.rxBus = rxBus
|
||||||
it.rh = rh
|
it.rh = rh
|
||||||
it.activePlugin = activePlugin
|
it.activePlugin = activePlugin
|
||||||
it.configBuilder = configBuilder
|
it.configBuilder = configBuilder
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package info.nightscout.pump.danaR.comm
|
package info.nightscout.pump.danaR.comm
|
||||||
|
|
||||||
import info.nightscout.androidaps.danar.comm.MessageHashTableR
|
import info.nightscout.androidaps.danar.comm.MessageHashTableR
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import org.junit.jupiter.api.Assertions
|
import org.junit.jupiter.api.Assertions
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.mockito.Mockito
|
import org.mockito.Mockito
|
||||||
|
@ -9,7 +9,7 @@ import org.mockito.Mockito
|
||||||
class MessageHashTableRTest : DanaRTestBase() {
|
class MessageHashTableRTest : DanaRTestBase() {
|
||||||
|
|
||||||
@Test fun runTest() {
|
@Test fun runTest() {
|
||||||
Mockito.`when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(Constraint(0.0))
|
Mockito.`when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(ConstraintObject(0.0, injector))
|
||||||
val messageHashTable = MessageHashTableR(injector)
|
val messageHashTable = MessageHashTableR(injector)
|
||||||
val testMessage = messageHashTable.findMessage(0x41f2)
|
val testMessage = messageHashTable.findMessage(0x41f2)
|
||||||
Assertions.assertEquals("CMD_HISTORY_ALL", testMessage.messageName)
|
Assertions.assertEquals("CMD_HISTORY_ALL", testMessage.messageName)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package info.nightscout.pump.danaR.comm
|
package info.nightscout.pump.danaR.comm
|
||||||
|
|
||||||
import info.nightscout.androidaps.danar.comm.MsgBolusStart
|
import info.nightscout.androidaps.danar.comm.MsgBolusStart
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import org.junit.jupiter.api.Assertions
|
import org.junit.jupiter.api.Assertions
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.mockito.Mockito.`when`
|
import org.mockito.Mockito.`when`
|
||||||
|
@ -9,7 +9,7 @@ import org.mockito.Mockito.`when`
|
||||||
class MsgBolusStartTest : DanaRTestBase() {
|
class MsgBolusStartTest : DanaRTestBase() {
|
||||||
|
|
||||||
@Test fun runTest() {
|
@Test fun runTest() {
|
||||||
`when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(Constraint(0.0))
|
`when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(ConstraintObject(0.0, injector))
|
||||||
val packet = MsgBolusStart(injector, 1.0)
|
val packet = MsgBolusStart(injector, 1.0)
|
||||||
|
|
||||||
// test message decoding
|
// test message decoding
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package info.nightscout.pump.danaR.comm
|
package info.nightscout.pump.danaR.comm
|
||||||
|
|
||||||
import info.nightscout.androidaps.danar.comm.MsgBolusStartWithSpeed
|
import info.nightscout.androidaps.danar.comm.MsgBolusStartWithSpeed
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import org.junit.jupiter.api.Assertions
|
import org.junit.jupiter.api.Assertions
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.mockito.Mockito
|
import org.mockito.Mockito
|
||||||
|
@ -9,7 +9,7 @@ import org.mockito.Mockito
|
||||||
class MsgBolusStartWithSpeedTest : DanaRTestBase() {
|
class MsgBolusStartWithSpeedTest : DanaRTestBase() {
|
||||||
|
|
||||||
@Test fun runTest() {
|
@Test fun runTest() {
|
||||||
Mockito.`when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(Constraint(0.0))
|
Mockito.`when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(ConstraintObject(0.0, injector))
|
||||||
val packet = MsgBolusStartWithSpeed(injector, 0.0, 0)
|
val packet = MsgBolusStartWithSpeed(injector, 0.0, 0)
|
||||||
|
|
||||||
// test message decoding
|
// test message decoding
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package info.nightscout.pump.danaR.comm
|
package info.nightscout.pump.danaR.comm
|
||||||
|
|
||||||
import info.nightscout.androidaps.danar.comm.MsgSetExtendedBolusStart
|
import info.nightscout.androidaps.danar.comm.MsgSetExtendedBolusStart
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import org.junit.jupiter.api.Assertions
|
import org.junit.jupiter.api.Assertions
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.mockito.Mockito.`when`
|
import org.mockito.Mockito.`when`
|
||||||
|
@ -9,7 +9,7 @@ import org.mockito.Mockito.`when`
|
||||||
class MsgSetExtendedBolusStartTest : DanaRTestBase() {
|
class MsgSetExtendedBolusStartTest : DanaRTestBase() {
|
||||||
|
|
||||||
@Test fun runTest() {
|
@Test fun runTest() {
|
||||||
`when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(Constraint(0.0))
|
`when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(ConstraintObject(0.0, injector))
|
||||||
val packet = MsgSetExtendedBolusStart(injector, 2.0, 2.toByte())
|
val packet = MsgSetExtendedBolusStart(injector, 2.0, 2.toByte())
|
||||||
|
|
||||||
// test message decoding
|
// test message decoding
|
||||||
|
|
|
@ -3,9 +3,8 @@ package info.nightscout.pump.danaRKorean
|
||||||
import dagger.android.AndroidInjector
|
import dagger.android.AndroidInjector
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.danaRKorean.DanaRKoreanPlugin
|
import info.nightscout.androidaps.danaRKorean.DanaRKoreanPlugin
|
||||||
import info.nightscout.interfaces.Constants
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
|
||||||
import info.nightscout.interfaces.plugin.PluginType
|
import info.nightscout.interfaces.plugin.PluginType
|
||||||
import info.nightscout.interfaces.profile.Instantiator
|
import info.nightscout.interfaces.profile.Instantiator
|
||||||
import info.nightscout.interfaces.pump.PumpSync
|
import info.nightscout.interfaces.pump.PumpSync
|
||||||
|
@ -22,7 +21,7 @@ import org.mockito.Mockito.`when`
|
||||||
|
|
||||||
class DanaRKoreanPluginTest : TestBaseWithProfile() {
|
class DanaRKoreanPluginTest : TestBaseWithProfile() {
|
||||||
|
|
||||||
@Mock lateinit var constraintChecker: Constraints
|
@Mock lateinit var constraintChecker: ConstraintsChecker
|
||||||
@Mock lateinit var commandQueue: CommandQueue
|
@Mock lateinit var commandQueue: CommandQueue
|
||||||
@Mock lateinit var pumpSync: PumpSync
|
@Mock lateinit var pumpSync: PumpSync
|
||||||
@Mock lateinit var instantiator: Instantiator
|
@Mock lateinit var instantiator: Instantiator
|
||||||
|
@ -34,7 +33,11 @@ class DanaRKoreanPluginTest : TestBaseWithProfile() {
|
||||||
private lateinit var danaRPlugin: DanaRKoreanPlugin
|
private lateinit var danaRPlugin: DanaRKoreanPlugin
|
||||||
|
|
||||||
val injector = HasAndroidInjector {
|
val injector = HasAndroidInjector {
|
||||||
AndroidInjector { }
|
AndroidInjector {
|
||||||
|
if (it is ConstraintObject<*>) {
|
||||||
|
it.aapsLogger = aapsLogger
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
|
@ -57,11 +60,11 @@ class DanaRKoreanPluginTest : TestBaseWithProfile() {
|
||||||
danaRPlugin.setPluginEnabled(PluginType.PUMP, true)
|
danaRPlugin.setPluginEnabled(PluginType.PUMP, true)
|
||||||
danaRPlugin.setPluginEnabled(PluginType.PUMP, true)
|
danaRPlugin.setPluginEnabled(PluginType.PUMP, true)
|
||||||
danaPump.maxBasal = 0.8
|
danaPump.maxBasal = 0.8
|
||||||
val c = Constraint(Constants.REALLYHIGHBASALRATE)
|
val c = ConstraintObject(Double.MAX_VALUE, injector)
|
||||||
danaRPlugin.applyBasalConstraints(c, validProfile)
|
danaRPlugin.applyBasalConstraints(c, validProfile)
|
||||||
Assertions.assertEquals(0.8, c.value(), 0.01)
|
Assertions.assertEquals(0.8, c.value(), 0.01)
|
||||||
Assertions.assertEquals("DanaRKorean: Limiting max basal rate to 0.80 U/h because of pump limit", c.getReasons(aapsLogger))
|
Assertions.assertEquals("DanaRKorean: Limiting max basal rate to 0.80 U/h because of pump limit", c.getReasons())
|
||||||
Assertions.assertEquals("DanaRKorean: Limiting max basal rate to 0.80 U/h because of pump limit", c.getMostLimitedReasons(aapsLogger))
|
Assertions.assertEquals("DanaRKorean: Limiting max basal rate to 0.80 U/h because of pump limit", c.getMostLimitedReasons())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test @Throws(Exception::class)
|
@Test @Throws(Exception::class)
|
||||||
|
@ -69,10 +72,10 @@ class DanaRKoreanPluginTest : TestBaseWithProfile() {
|
||||||
danaRPlugin.setPluginEnabled(PluginType.PUMP, true)
|
danaRPlugin.setPluginEnabled(PluginType.PUMP, true)
|
||||||
danaRPlugin.setPluginEnabled(PluginType.PUMP, true)
|
danaRPlugin.setPluginEnabled(PluginType.PUMP, true)
|
||||||
danaPump.maxBasal = 0.8
|
danaPump.maxBasal = 0.8
|
||||||
val c = Constraint(Constants.REALLYHIGHPERCENTBASALRATE)
|
val c = ConstraintObject(Int.MAX_VALUE, injector)
|
||||||
danaRPlugin.applyBasalPercentConstraints(c, validProfile)
|
danaRPlugin.applyBasalPercentConstraints(c, validProfile)
|
||||||
Assertions.assertEquals(200, c.value())
|
Assertions.assertEquals(200, c.value())
|
||||||
Assertions.assertEquals("DanaRKorean: Limiting max percent rate to 200% because of pump limit", c.getReasons(aapsLogger))
|
Assertions.assertEquals("DanaRKorean: Limiting max percent rate to 200% because of pump limit", c.getReasons())
|
||||||
Assertions.assertEquals("DanaRKorean: Limiting max percent rate to 200% because of pump limit", c.getMostLimitedReasons(aapsLogger))
|
Assertions.assertEquals("DanaRKorean: Limiting max percent rate to 200% because of pump limit", c.getMostLimitedReasons())
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
package info.nightscout.pump.danaRKorean.comm
|
package info.nightscout.pump.danaRKorean.comm
|
||||||
|
|
||||||
import info.nightscout.androidaps.danaRKorean.comm.MessageHashTableRKorean
|
import info.nightscout.androidaps.danaRKorean.comm.MessageHashTableRKorean
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.pump.danaR.comm.DanaRTestBase
|
import info.nightscout.pump.danaR.comm.DanaRTestBase
|
||||||
import org.junit.jupiter.api.Assertions
|
import org.junit.jupiter.api.Assertions
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
@ -10,7 +10,7 @@ import org.mockito.Mockito
|
||||||
class MessageHashTableRKoreanTest : DanaRTestBase() {
|
class MessageHashTableRKoreanTest : DanaRTestBase() {
|
||||||
|
|
||||||
@Test fun runTest() {
|
@Test fun runTest() {
|
||||||
Mockito.`when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(Constraint(0.0))
|
Mockito.`when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(ConstraintObject(0.0, injector))
|
||||||
val messageHashTable = MessageHashTableRKorean(injector)
|
val messageHashTable = MessageHashTableRKorean(injector)
|
||||||
val testMessage = messageHashTable.findMessage(0x41f2)
|
val testMessage = messageHashTable.findMessage(0x41f2)
|
||||||
Assertions.assertEquals("CMD_HISTORY_ALL", testMessage.messageName)
|
Assertions.assertEquals("CMD_HISTORY_ALL", testMessage.messageName)
|
||||||
|
|
|
@ -3,9 +3,8 @@ package info.nightscout.pump.danaRv2
|
||||||
import dagger.android.AndroidInjector
|
import dagger.android.AndroidInjector
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.danaRv2.DanaRv2Plugin
|
import info.nightscout.androidaps.danaRv2.DanaRv2Plugin
|
||||||
import info.nightscout.interfaces.Constants
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
|
||||||
import info.nightscout.interfaces.plugin.PluginType
|
import info.nightscout.interfaces.plugin.PluginType
|
||||||
import info.nightscout.interfaces.profile.Instantiator
|
import info.nightscout.interfaces.profile.Instantiator
|
||||||
import info.nightscout.interfaces.pump.DetailedBolusInfoStorage
|
import info.nightscout.interfaces.pump.DetailedBolusInfoStorage
|
||||||
|
@ -24,7 +23,7 @@ import org.mockito.Mockito.`when`
|
||||||
|
|
||||||
class DanaRv2PluginTest : TestBaseWithProfile() {
|
class DanaRv2PluginTest : TestBaseWithProfile() {
|
||||||
|
|
||||||
@Mock lateinit var constraintChecker: Constraints
|
@Mock lateinit var constraintChecker: ConstraintsChecker
|
||||||
@Mock lateinit var commandQueue: CommandQueue
|
@Mock lateinit var commandQueue: CommandQueue
|
||||||
@Mock lateinit var detailedBolusInfoStorage: DetailedBolusInfoStorage
|
@Mock lateinit var detailedBolusInfoStorage: DetailedBolusInfoStorage
|
||||||
@Mock lateinit var temporaryBasalStorage: TemporaryBasalStorage
|
@Mock lateinit var temporaryBasalStorage: TemporaryBasalStorage
|
||||||
|
@ -38,7 +37,11 @@ class DanaRv2PluginTest : TestBaseWithProfile() {
|
||||||
private lateinit var danaRv2Plugin: DanaRv2Plugin
|
private lateinit var danaRv2Plugin: DanaRv2Plugin
|
||||||
|
|
||||||
val injector = HasAndroidInjector {
|
val injector = HasAndroidInjector {
|
||||||
AndroidInjector { }
|
AndroidInjector {
|
||||||
|
if (it is ConstraintObject<*>) {
|
||||||
|
it.aapsLogger = aapsLogger
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
|
@ -61,11 +64,11 @@ class DanaRv2PluginTest : TestBaseWithProfile() {
|
||||||
danaRv2Plugin.setPluginEnabled(PluginType.PUMP, true)
|
danaRv2Plugin.setPluginEnabled(PluginType.PUMP, true)
|
||||||
danaRv2Plugin.setPluginEnabled(PluginType.PUMP, true)
|
danaRv2Plugin.setPluginEnabled(PluginType.PUMP, true)
|
||||||
danaPump.maxBasal = 0.8
|
danaPump.maxBasal = 0.8
|
||||||
val c = Constraint(Constants.REALLYHIGHBASALRATE)
|
val c = ConstraintObject(Double.MAX_VALUE, injector)
|
||||||
danaRv2Plugin.applyBasalConstraints(c, validProfile)
|
danaRv2Plugin.applyBasalConstraints(c, validProfile)
|
||||||
Assertions.assertEquals(0.8, c.value(), 0.01)
|
Assertions.assertEquals(0.8, c.value(), 0.01)
|
||||||
Assertions.assertEquals("DanaRv2: Limiting max basal rate to 0.80 U/h because of pump limit", c.getReasons(aapsLogger))
|
Assertions.assertEquals("DanaRv2: Limiting max basal rate to 0.80 U/h because of pump limit", c.getReasons())
|
||||||
Assertions.assertEquals("DanaRv2: Limiting max basal rate to 0.80 U/h because of pump limit", c.getMostLimitedReasons(aapsLogger))
|
Assertions.assertEquals("DanaRv2: Limiting max basal rate to 0.80 U/h because of pump limit", c.getMostLimitedReasons())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -73,10 +76,10 @@ class DanaRv2PluginTest : TestBaseWithProfile() {
|
||||||
danaRv2Plugin.setPluginEnabled(PluginType.PUMP, true)
|
danaRv2Plugin.setPluginEnabled(PluginType.PUMP, true)
|
||||||
danaRv2Plugin.setPluginEnabled(PluginType.PUMP, true)
|
danaRv2Plugin.setPluginEnabled(PluginType.PUMP, true)
|
||||||
danaPump.maxBasal = 0.8
|
danaPump.maxBasal = 0.8
|
||||||
val c = Constraint(Constants.REALLYHIGHPERCENTBASALRATE)
|
val c = ConstraintObject(Int.MAX_VALUE, injector)
|
||||||
danaRv2Plugin.applyBasalPercentConstraints(c, validProfile)
|
danaRv2Plugin.applyBasalPercentConstraints(c, validProfile)
|
||||||
Assertions.assertEquals(200, c.value())
|
Assertions.assertEquals(200, c.value())
|
||||||
Assertions.assertEquals("DanaRv2: Limiting max percent rate to 200% because of pump limit", c.getReasons(aapsLogger))
|
Assertions.assertEquals("DanaRv2: Limiting max percent rate to 200% because of pump limit", c.getReasons())
|
||||||
Assertions.assertEquals("DanaRv2: Limiting max percent rate to 200% because of pump limit", c.getMostLimitedReasons(aapsLogger))
|
Assertions.assertEquals("DanaRv2: Limiting max percent rate to 200% because of pump limit", c.getMostLimitedReasons())
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@ package info.nightscout.pump.danaRv2.comm
|
||||||
import info.nightscout.androidaps.danaRv2.comm.MessageHashTableRv2
|
import info.nightscout.androidaps.danaRv2.comm.MessageHashTableRv2
|
||||||
import info.nightscout.androidaps.danaRv2.comm.MsgStatusAPS_v2
|
import info.nightscout.androidaps.danaRv2.comm.MsgStatusAPS_v2
|
||||||
import info.nightscout.androidaps.danar.comm.MessageBase
|
import info.nightscout.androidaps.danar.comm.MessageBase
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.pump.danaR.comm.DanaRTestBase
|
import info.nightscout.pump.danaR.comm.DanaRTestBase
|
||||||
import org.junit.jupiter.api.Assertions
|
import org.junit.jupiter.api.Assertions
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
@ -13,7 +13,7 @@ class MessageHashTableRv2Test : DanaRTestBase() {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun runTest() {
|
fun runTest() {
|
||||||
`when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(Constraint(0.0))
|
`when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(ConstraintObject(0.0, injector))
|
||||||
val messageHashTableRv2 = MessageHashTableRv2(injector)
|
val messageHashTableRv2 = MessageHashTableRv2(injector)
|
||||||
val forTesting: MessageBase = MsgStatusAPS_v2(injector)
|
val forTesting: MessageBase = MsgStatusAPS_v2(injector)
|
||||||
val testPacket: MessageBase = messageHashTableRv2.findMessage(forTesting.command)
|
val testPacket: MessageBase = messageHashTableRv2.findMessage(forTesting.command)
|
||||||
|
|
|
@ -8,10 +8,12 @@ import android.os.IBinder
|
||||||
import android.text.format.DateFormat
|
import android.text.format.DateFormat
|
||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.core.ui.toast.ToastUtils
|
import info.nightscout.core.ui.toast.ToastUtils
|
||||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.interfaces.constraints.Constraint
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
|
import info.nightscout.interfaces.constraints.PluginConstraints
|
||||||
import info.nightscout.interfaces.notifications.Notification
|
import info.nightscout.interfaces.notifications.Notification
|
||||||
import info.nightscout.interfaces.plugin.OwnDatabasePlugin
|
import info.nightscout.interfaces.plugin.OwnDatabasePlugin
|
||||||
import info.nightscout.interfaces.plugin.PluginDescription
|
import info.nightscout.interfaces.plugin.PluginDescription
|
||||||
|
@ -68,7 +70,7 @@ class DanaRSPlugin @Inject constructor(
|
||||||
private val rxBus: RxBus,
|
private val rxBus: RxBus,
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
rh: ResourceHelper,
|
rh: ResourceHelper,
|
||||||
private val constraintChecker: Constraints,
|
private val constraintChecker: ConstraintsChecker,
|
||||||
private val profileFunction: ProfileFunction,
|
private val profileFunction: ProfileFunction,
|
||||||
private val sp: SP,
|
private val sp: SP,
|
||||||
commandQueue: CommandQueue,
|
commandQueue: CommandQueue,
|
||||||
|
@ -92,7 +94,7 @@ class DanaRSPlugin @Inject constructor(
|
||||||
.preferencesId(R.xml.pref_danars)
|
.preferencesId(R.xml.pref_danars)
|
||||||
.description(info.nightscout.pump.dana.R.string.description_pump_dana_rs),
|
.description(info.nightscout.pump.dana.R.string.description_pump_dana_rs),
|
||||||
injector, aapsLogger, rh, commandQueue
|
injector, aapsLogger, rh, commandQueue
|
||||||
), Pump, Dana, Constraints, OwnDatabasePlugin {
|
), Pump, Dana, PluginConstraints, OwnDatabasePlugin {
|
||||||
|
|
||||||
private val disposable = CompositeDisposable()
|
private val disposable = CompositeDisposable()
|
||||||
private var danaRSService: DanaRSService? = null
|
private var danaRSService: DanaRSService? = null
|
||||||
|
@ -202,18 +204,22 @@ class DanaRSPlugin @Inject constructor(
|
||||||
|
|
||||||
// Constraints interface
|
// Constraints interface
|
||||||
override fun applyBasalConstraints(absoluteRate: Constraint<Double>, profile: Profile): Constraint<Double> {
|
override fun applyBasalConstraints(absoluteRate: Constraint<Double>, profile: Profile): Constraint<Double> {
|
||||||
absoluteRate.setIfSmaller(aapsLogger, danaPump.maxBasal, rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, danaPump.maxBasal, rh.gs(info.nightscout.core.ui.R.string.pumplimit)), this)
|
absoluteRate.setIfSmaller(danaPump.maxBasal, rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, danaPump.maxBasal, rh.gs(info.nightscout.core.ui.R.string.pumplimit)), this)
|
||||||
return absoluteRate
|
return absoluteRate
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun applyBasalPercentConstraints(percentRate: Constraint<Int>, profile: Profile): Constraint<Int> {
|
override fun applyBasalPercentConstraints(percentRate: Constraint<Int>, profile: Profile): Constraint<Int> {
|
||||||
percentRate.setIfGreater(aapsLogger, 0, rh.gs(info.nightscout.core.ui.R.string.limitingpercentrate, 0, rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), this)
|
percentRate.setIfGreater(0, rh.gs(info.nightscout.core.ui.R.string.limitingpercentrate, 0, rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), this)
|
||||||
percentRate.setIfSmaller(aapsLogger, pumpDescription.maxTempPercent, rh.gs(info.nightscout.core.ui.R.string.limitingpercentrate, pumpDescription.maxTempPercent, rh.gs(info.nightscout.core.ui.R.string.pumplimit)), this)
|
percentRate.setIfSmaller(
|
||||||
|
pumpDescription.maxTempPercent,
|
||||||
|
rh.gs(info.nightscout.core.ui.R.string.limitingpercentrate, pumpDescription.maxTempPercent, rh.gs(info.nightscout.core.ui.R.string.pumplimit)),
|
||||||
|
this
|
||||||
|
)
|
||||||
return percentRate
|
return percentRate
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun applyBolusConstraints(insulin: Constraint<Double>): Constraint<Double> {
|
override fun applyBolusConstraints(insulin: Constraint<Double>): Constraint<Double> {
|
||||||
insulin.setIfSmaller(aapsLogger, danaPump.maxBolus, rh.gs(info.nightscout.core.ui.R.string.limitingbolus, danaPump.maxBolus, rh.gs(info.nightscout.core.ui.R.string.pumplimit)), this)
|
insulin.setIfSmaller(danaPump.maxBolus, rh.gs(info.nightscout.core.ui.R.string.limitingbolus, danaPump.maxBolus, rh.gs(info.nightscout.core.ui.R.string.pumplimit)), this)
|
||||||
return insulin
|
return insulin
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,7 +288,7 @@ class DanaRSPlugin @Inject constructor(
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
override fun deliverTreatment(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult {
|
override fun deliverTreatment(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult {
|
||||||
detailedBolusInfo.insulin = constraintChecker.applyBolusConstraints(Constraint(detailedBolusInfo.insulin)).value()
|
detailedBolusInfo.insulin = constraintChecker.applyBolusConstraints(ConstraintObject(detailedBolusInfo.insulin, injector)).value()
|
||||||
return if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) {
|
return if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) {
|
||||||
val preferencesSpeed = sp.getInt(info.nightscout.pump.dana.R.string.key_danars_bolusspeed, 0)
|
val preferencesSpeed = sp.getInt(info.nightscout.pump.dana.R.string.key_danars_bolusspeed, 0)
|
||||||
var speed = 12
|
var speed = 12
|
||||||
|
@ -337,7 +343,7 @@ class DanaRSPlugin @Inject constructor(
|
||||||
// This is called from APS
|
// This is called from APS
|
||||||
@Synchronized
|
@Synchronized
|
||||||
override fun setTempBasalAbsolute(absoluteRate: Double, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: PumpSync.TemporaryBasalType): PumpEnactResult {
|
override fun setTempBasalAbsolute(absoluteRate: Double, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: PumpSync.TemporaryBasalType): PumpEnactResult {
|
||||||
val absoluteAfterConstrain = constraintChecker.applyBasalConstraints(Constraint(absoluteRate), profile).value()
|
val absoluteAfterConstrain = constraintChecker.applyBasalConstraints(ConstraintObject(absoluteRate, injector), profile).value()
|
||||||
var doTempOff = baseBasalRate - absoluteAfterConstrain == 0.0
|
var doTempOff = baseBasalRate - absoluteAfterConstrain == 0.0
|
||||||
val doLowTemp = absoluteAfterConstrain < baseBasalRate
|
val doLowTemp = absoluteAfterConstrain < baseBasalRate
|
||||||
val doHighTemp = absoluteAfterConstrain > baseBasalRate
|
val doHighTemp = absoluteAfterConstrain > baseBasalRate
|
||||||
|
@ -413,7 +419,7 @@ class DanaRSPlugin @Inject constructor(
|
||||||
@Synchronized
|
@Synchronized
|
||||||
override fun setTempBasalPercent(percent: Int, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: PumpSync.TemporaryBasalType): PumpEnactResult {
|
override fun setTempBasalPercent(percent: Int, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: PumpSync.TemporaryBasalType): PumpEnactResult {
|
||||||
val result = PumpEnactResult(injector)
|
val result = PumpEnactResult(injector)
|
||||||
var percentAfterConstraint = constraintChecker.applyBasalPercentConstraints(Constraint(percent), profile).value()
|
var percentAfterConstraint = constraintChecker.applyBasalPercentConstraints(ConstraintObject(percent, injector), profile).value()
|
||||||
if (percentAfterConstraint < 0) {
|
if (percentAfterConstraint < 0) {
|
||||||
result.isTempCancel = false
|
result.isTempCancel = false
|
||||||
result.enacted = false
|
result.enacted = false
|
||||||
|
@ -483,7 +489,7 @@ class DanaRSPlugin @Inject constructor(
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
override fun setExtendedBolus(insulin: Double, durationInMinutes: Int): PumpEnactResult {
|
override fun setExtendedBolus(insulin: Double, durationInMinutes: Int): PumpEnactResult {
|
||||||
var insulinAfterConstraint = constraintChecker.applyExtendedBolusConstraints(Constraint(insulin)).value()
|
var insulinAfterConstraint = constraintChecker.applyExtendedBolusConstraints(ConstraintObject(insulin, injector)).value()
|
||||||
// needs to be rounded
|
// needs to be rounded
|
||||||
val durationInHalfHours = max(durationInMinutes / 30, 1)
|
val durationInHalfHours = max(durationInMinutes / 30, 1)
|
||||||
insulinAfterConstraint = Round.roundTo(insulinAfterConstraint, pumpDescription.extendedBolusStep)
|
insulinAfterConstraint = Round.roundTo(insulinAfterConstraint, pumpDescription.extendedBolusStep)
|
||||||
|
|
|
@ -2,8 +2,8 @@ package info.nightscout.pump.danars.comm
|
||||||
|
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.danars.encryption.BleEncryption
|
import info.nightscout.androidaps.danars.encryption.BleEncryption
|
||||||
import info.nightscout.interfaces.constraints.Constraint
|
import info.nightscout.core.constraints.ConstraintObject
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.pump.dana.DanaPump
|
import info.nightscout.pump.dana.DanaPump
|
||||||
import info.nightscout.rx.logging.LTag
|
import info.nightscout.rx.logging.LTag
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -15,13 +15,13 @@ class DanaRSPacketBolusSetStepBolusStart(
|
||||||
) : DanaRSPacket(injector) {
|
) : DanaRSPacket(injector) {
|
||||||
|
|
||||||
@Inject lateinit var danaPump: DanaPump
|
@Inject lateinit var danaPump: DanaPump
|
||||||
@Inject lateinit var constraintChecker: Constraints
|
@Inject lateinit var constraintChecker: ConstraintsChecker
|
||||||
|
|
||||||
init {
|
init {
|
||||||
opCode = BleEncryption.DANAR_PACKET__OPCODE_BOLUS__SET_STEP_BOLUS_START
|
opCode = BleEncryption.DANAR_PACKET__OPCODE_BOLUS__SET_STEP_BOLUS_START
|
||||||
// Speed 0 => 12 sec/U, 1 => 30 sec/U, 2 => 60 sec/U
|
// Speed 0 => 12 sec/U, 1 => 30 sec/U, 2 => 60 sec/U
|
||||||
// HARDCODED LIMIT - if there is one that could be created
|
// HARDCODED LIMIT - if there is one that could be created
|
||||||
amount = constraintChecker.applyBolusConstraints(Constraint(amount)).value()
|
amount = constraintChecker.applyBolusConstraints(ConstraintObject(amount, injector)).value()
|
||||||
aapsLogger.debug(LTag.PUMPCOMM, "Bolus start : $amount speed: $speed")
|
aapsLogger.debug(LTag.PUMPCOMM, "Bolus start : $amount speed: $speed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import dagger.android.DaggerService
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||||
import info.nightscout.interfaces.Constants
|
import info.nightscout.interfaces.Constants
|
||||||
import info.nightscout.interfaces.constraints.Constraints
|
import info.nightscout.interfaces.constraints.ConstraintsChecker
|
||||||
import info.nightscout.interfaces.notifications.Notification
|
import info.nightscout.interfaces.notifications.Notification
|
||||||
import info.nightscout.interfaces.plugin.ActivePlugin
|
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||||
import info.nightscout.interfaces.profile.Profile
|
import info.nightscout.interfaces.profile.Profile
|
||||||
|
@ -103,7 +103,7 @@ class DanaRSService : DaggerService() {
|
||||||
@Inject lateinit var danaRSPlugin: DanaRSPlugin
|
@Inject lateinit var danaRSPlugin: DanaRSPlugin
|
||||||
@Inject lateinit var danaPump: DanaPump
|
@Inject lateinit var danaPump: DanaPump
|
||||||
@Inject lateinit var activePlugin: ActivePlugin
|
@Inject lateinit var activePlugin: ActivePlugin
|
||||||
@Inject lateinit var constraintChecker: Constraints
|
@Inject lateinit var constraintChecker: ConstraintsChecker
|
||||||
@Inject lateinit var uiInteraction: UiInteraction
|
@Inject lateinit var uiInteraction: UiInteraction
|
||||||
@Inject lateinit var bleComm: BLEComm
|
@Inject lateinit var bleComm: BLEComm
|
||||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue