From d939f7ba99c9fcee08e7fb58540919b5e6b7c5de Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 19 Sep 2023 13:50:25 +0200 Subject: [PATCH] refactor ConstraintObject --- .../info/nightscout/sharedtests/TestBase.kt | 4 + .../sharedtests/TestBaseWithProfile.kt | 5 +- .../nightscout/androidaps/RealPumpTest.kt | 186 +++++---- .../androidaps/SetupWizardActivityTest.kt | 354 ++++++++-------- .../nightscout/androidaps/MainActivity.kt | 4 +- .../info/nightscout/androidaps/MainApp.kt | 3 +- .../androidaps/di/ServicesModule.kt | 2 - .../plugins/aps/loop/LoopPluginTest.kt | 8 +- .../configBuilder/ConfigBuilderPluginTest.kt | 3 +- .../constraints/ConstraintsCheckerTest.kt | 42 +- .../plugins/safety/SafetyPluginTest.kt | 136 ++++--- .../info/nightscout/interfaces/Constants.kt | 5 - .../interfaces/constraints/Constraint.kt | 121 +----- .../interfaces/constraints/Constraints.kt | 58 --- .../constraints/ConstraintsChecker.kt | 36 ++ .../constraints/PluginConstraints.kt | 28 ++ core/main/build.gradle | 1 + .../core/constraints/ConstraintObject.kt | 121 ++++++ .../nightscout/core/wizard/BolusWizard.kt | 8 +- .../nightscout/core/data/ConstraintTest.kt | 62 +-- .../info/nightscout/core/data/IobTotalTest.kt | 3 +- .../info/nightscout/core/data/ProfileTest.kt | 7 +- .../nightscout/core/utils/DateUtilTest.kt | 44 +- core/main/test_dependencies.gradle | 1 + .../queue/CommandQueueImplementation.kt | 16 +- .../queue/CommandQueueImplementationTest.kt | 19 +- .../implementation/queue/QueueThreadTest.kt | 17 +- .../implementation/wizard/BolusWizardTest.kt | 9 +- .../pump/insight/LocalInsightPlugin.java | 25 +- .../nightscout/plugins/aps/APSResultObject.kt | 26 +- .../nightscout/plugins/aps/OpenAPSFragment.kt | 2 +- .../plugins/aps/loop/LoopFragment.kt | 10 +- .../nightscout/plugins/aps/loop/LoopPlugin.kt | 13 +- .../openAPSAMA/DetermineBasalAdapterAMAJS.kt | 7 +- .../aps/openAPSAMA/OpenAPSAMAPlugin.kt | 21 +- .../openAPSSMB/DetermineBasalAdapterSMBJS.kt | 4 +- .../aps/openAPSSMB/OpenAPSSMBPlugin.kt | 43 +- .../OpenAPSSMBDynamicISFPlugin.kt | 4 +- .../plugins/aps/loop/APSResultTest.kt | 24 +- plugins/automation/build.gradle | 1 + .../nightscout/automation/AutomationPlugin.kt | 8 +- .../automation/AutomationEventTest.kt | 3 +- .../automation/BolusTimerImplTest.kt | 16 +- .../automation/CarbTimerImplTest.kt | 9 +- .../automation/actions/ActionAlarmTest.kt | 2 - .../actions/ActionNotificationTest.kt | 6 +- .../automation/actions/ActionsTestBase.kt | 12 +- .../automation/triggers/TriggerTestBase.kt | 3 +- ...aintsImpl.kt => ConstraintsCheckerImpl.kt} | 116 ++++-- .../bgQualityCheck/BgQualityCheckPlugin.kt | 6 +- .../di/PluginsConstraintsModule.kt | 6 +- .../constraints/dstHelper/DstHelperPlugin.kt | 6 +- .../objectives/ObjectivesPlugin.kt | 20 +- .../objectives/objectives/Objective4.kt | 8 +- .../objectives/objectives/Objective5.kt | 4 +- .../objectives/objectives/Objective6.kt | 4 +- .../phoneChecker/PhoneCheckerPlugin.kt | 20 +- .../constraints/safety/SafetyPlugin.kt | 64 +-- .../SignatureVerifierPlugin.kt | 6 +- .../storage/StorageConstraintPlugin.kt | 6 +- .../versionChecker/VersionCheckerPlugin.kt | 10 +- .../BgQualityCheckPluginTest.kt | 384 ++++++++++++++++-- .../objectives/ObjectivesPluginTest.kt | 25 +- .../storage/StorageConstraintPluginTest.kt | 13 +- .../insulin/InsulinOrefFreePeakPluginTest.kt | 2 - .../general/overview/OverviewFragment.kt | 8 +- .../smsCommunicator/SmsCommunicatorPlugin.kt | 16 +- .../wear/wearintegration/DataHandlerMobile.kt | 22 +- .../SmsCommunicatorPluginTest.kt | 29 +- .../plugins/iob/AutosensDataStoreTest.kt | 3 +- .../sensitivity/SensitivityOref1Plugin.kt | 6 +- .../sync/nsclient/ReceiverDelegateTest.kt | 2 - .../nsclientV3/workers/DataSyncWorkerTest.kt | 2 - .../nsclientV3/workers/LoadBgWorkerTest.kt | 2 - .../nightscout/pump/combo/ComboPlugin.java | 86 ++-- .../nightscout/pump/combo/ComboPluginTest.kt | 13 +- pump/combov2/build.gradle | 1 + .../nightscout/pump/combov2/ComboV2Plugin.kt | 211 ++++++---- .../danaRKorean/DanaRKoreanPlugin.kt | 12 +- .../services/DanaRKoreanExecutionService.java | 16 +- .../androidaps/danaRv2/DanaRv2Plugin.java | 41 +- .../androidaps/danar/AbstractDanaRPlugin.java | 23 +- .../androidaps/danar/DanaRPlugin.java | 43 +- .../androidaps/danar/comm/MessageBase.kt | 4 +- .../androidaps/danar/comm/MsgBolusStart.kt | 5 +- .../danar/comm/MsgBolusStartWithSpeed.kt | 9 +- .../danar/comm/MsgSetExtendedBolusStart.kt | 15 +- .../nightscout/pump/danaR/DanaRPluginTest.kt | 25 +- .../pump/danaR/comm/DanaRTestBase.kt | 11 +- .../pump/danaR/comm/MessageHashTableRTest.kt | 4 +- .../pump/danaR/comm/MsgBolusStartTest.kt | 4 +- .../danaR/comm/MsgBolusStartWithSpeedTest.kt | 4 +- .../comm/MsgSetExtendedBolusStartTest.kt | 4 +- .../pump/danaRKorean/DanaRKoreanPluginTest.kt | 25 +- .../comm/MessageHashTableRKoreanTest.kt | 4 +- .../pump/danaRv2/DanaRv2PluginTest.kt | 25 +- .../danaRv2/comm/MessageHashTableRv2Test.kt | 4 +- .../nightscout/pump/danars/DanaRSPlugin.kt | 28 +- .../DanaRSPacketBolusSetStepBolusStart.kt | 8 +- .../pump/danars/services/DanaRSService.kt | 4 +- .../pump/danars/DanaRSPluginTest.kt | 19 +- .../nightscout/pump/danars/DanaRSTestBase.kt | 11 + .../danars/comm/DanaRsMessageHashTableTest.kt | 8 +- .../DanaRsPacketBolusSetStepBolusStartTest.kt | 8 +- ...naRsPacketNotifyDeliveryRateDisplayTest.kt | 4 +- .../pump/diaconn/DiaconnG8Plugin.kt | 26 +- .../pump/medtronic/MedtronicTestBase.kt | 3 - .../comm/MedtronicHistoryDataUTest.kt | 4 - .../nightscout/pump/medtrum/MedtrumPlugin.kt | 10 +- .../pump/medtrum/services/MedtrumService.kt | 6 +- pump/omnipod-dash/build.gradle | 1 + .../omnipod/dash/history/DashHistoryTest.kt | 1 - .../omnipod/eros/history/ErosHistoryTest.kt | 1 + .../omnipod/eros/OmnipodErosPumpPluginTest.kt | 6 +- .../manager/AapsErosPodStateManagerTest.kt | 4 - .../pump/common/PumpPluginAbstract.kt | 4 +- .../pump/virtual/VirtualPumpPluginUTest.kt | 2 - .../info/nightscout/ui/dialogs/CarbsDialog.kt | 10 +- .../ui/dialogs/ExtendedBolusDialog.kt | 10 +- .../info/nightscout/ui/dialogs/FillDialog.kt | 10 +- .../nightscout/ui/dialogs/InsulinDialog.kt | 10 +- .../info/nightscout/ui/dialogs/LoopDialog.kt | 18 +- .../nightscout/ui/dialogs/TempBasalDialog.kt | 12 +- .../nightscout/ui/dialogs/TempTargetDialog.kt | 4 +- .../nightscout/ui/dialogs/TreatmentDialog.kt | 14 +- .../nightscout/ui/dialogs/WizardDialog.kt | 8 +- .../java/info/nightscout/ui/widget/Widget.kt | 10 +- 127 files changed, 1818 insertions(+), 1367 deletions(-) delete mode 100644 app/src/main/java/info/nightscout/androidaps/di/ServicesModule.kt delete mode 100644 core/interfaces/src/main/java/info/nightscout/interfaces/constraints/Constraints.kt create mode 100644 core/interfaces/src/main/java/info/nightscout/interfaces/constraints/ConstraintsChecker.kt create mode 100644 core/interfaces/src/main/java/info/nightscout/interfaces/constraints/PluginConstraints.kt create mode 100644 core/main/src/main/java/info/nightscout/core/constraints/ConstraintObject.kt rename plugins/constraints/src/main/java/info/nightscout/plugins/constraints/{ConstraintsImpl.kt => ConstraintsCheckerImpl.kt} (57%) diff --git a/app-wear-shared/shared-tests/src/main/java/info/nightscout/sharedtests/TestBase.kt b/app-wear-shared/shared-tests/src/main/java/info/nightscout/sharedtests/TestBase.kt index 35f4960822..dabbc8c6fa 100644 --- a/app-wear-shared/shared-tests/src/main/java/info/nightscout/sharedtests/TestBase.kt +++ b/app-wear-shared/shared-tests/src/main/java/info/nightscout/sharedtests/TestBase.kt @@ -2,6 +2,8 @@ package info.nightscout.sharedtests import android.annotation.SuppressLint 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 org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.extension.ExtendWith @@ -19,11 +21,13 @@ open class TestBase { val aapsLogger = AAPSLoggerTest() val aapsSchedulers: AapsSchedulers = TestAapsSchedulers() + lateinit var rxBus: RxBus @BeforeEach fun setupLocale() { Locale.setDefault(Locale.ENGLISH) System.setProperty("disableFirebase", "true") + rxBus = RxBusImpl(aapsSchedulers, aapsLogger) } @SuppressLint("CheckResult") diff --git a/app-wear-shared/shared-tests/src/main/java/info/nightscout/sharedtests/TestBaseWithProfile.kt b/app-wear-shared/shared-tests/src/main/java/info/nightscout/sharedtests/TestBaseWithProfile.kt index 8a03a6fbbb..67bb7a48e0 100644 --- a/app-wear-shared/shared-tests/src/main/java/info/nightscout/sharedtests/TestBaseWithProfile.kt +++ b/app-wear-shared/shared-tests/src/main/java/info/nightscout/sharedtests/TestBaseWithProfile.kt @@ -19,10 +19,10 @@ import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileStore import info.nightscout.interfaces.utils.DecimalFormatter 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.ResourceHelper import info.nightscout.shared.sharedPreferences.SP +import info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.DateUtilImpl import org.json.JSONObject import org.junit.jupiter.api.BeforeEach @@ -45,11 +45,10 @@ open class TestBaseWithProfile : TestBase() { @Mock lateinit var context: Context @Mock lateinit var sp: SP - lateinit var dateUtil: DateUtilImpl + lateinit var dateUtil: DateUtil lateinit var profileUtil: ProfileUtil lateinit var decimalFormatter: DecimalFormatter lateinit var hardLimits: HardLimits - val rxBus = RxBusImpl(aapsSchedulers, aapsLogger) val profileInjector = HasAndroidInjector { AndroidInjector { diff --git a/app/src/androidTest/java/info/nightscout/androidaps/RealPumpTest.kt b/app/src/androidTest/java/info/nightscout/androidaps/RealPumpTest.kt index 43ff3c41e7..c248fcbfb3 100644 --- a/app/src/androidTest/java/info/nightscout/androidaps/RealPumpTest.kt +++ b/app/src/androidTest/java/info/nightscout/androidaps/RealPumpTest.kt @@ -1,102 +1,98 @@ package info.nightscout.androidaps -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.filters.LargeTest -import org.junit.runner.RunWith - -@LargeTest -@RunWith(AndroidJUnit4::class) +//@LargeTest +//@RunWith(AndroidJUnit4::class) class RealPumpTest { -/* - companion object { - const val R_PASSWORD = 1234 - const val R_SERIAL = "PBB00013LR_P" - } - - private val validProfile = "{\"dia\":\"6\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"10\"},{\"time\":\"2:00\",\"value\":\"11\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" - - @Inject lateinit var pump : info.nightscout.androidaps.danaRv2.DanaRv2Plugin - @Inject lateinit var randomBgPlugin :RandomBgPlugin - @Inject lateinit var localProfilePlugin: LocalProfilePlugin - @Inject lateinit var profileFunction: ProfileFunction - @Inject lateinit var insulinOrefUltraRapidActingPlugin: InsulinOrefUltraRapidActingPlugin - @Inject lateinit var sensitivityOref1Plugin: SensitivityOref1Plugin - @Inject lateinit var openAPSSMBPlugin: OpenAPSSMBPlugin - @Inject lateinit var loopPlugin: LoopPlugin - @Inject lateinit var actionsPlugin: ActionsPlugin - @Inject lateinit var configBuilderPlugin: ConfigBuilderPlugin - @Inject lateinit var objectivesPlugin: ObjectivesPlugin - @Inject lateinit var treatmentsPlugin: TreatmentsPlugin - @Inject lateinit var sp: SP - - @Rule - @JvmField - var mActivityTestRule = ActivityTestRule(MainActivity::class.java) - - @Rule - @JvmField - var mGrantPermissionRule: GrantPermissionRule = - GrantPermissionRule.grant( - android.Manifest.permission.ACCESS_FINE_LOCATION, - android.Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, - android.Manifest.permission.WRITE_EXTERNAL_STORAGE - ) - - @Before - fun clear() { - sp.clear() - sp.putBoolean(R.string.key_setupwizard_processed, true) - sp.putString(R.string.key_aps_mode, "closed") - MainApp.getDbHelper().resetDatabases() - MainApp.devBranch = false - } - - private fun preparePlugins() { - // Source - configBuilderPlugin.performPluginSwitch(randomBgPlugin,true, PluginType.BGSOURCE) - // Profile - configBuilderPlugin.performPluginSwitch(localProfilePlugin, true, PluginType.PROFILE) - val profile = Profile(JSONObject(validProfile), Constants.MGDL) - Assert.assertTrue(profile.isValid("Test")) - localProfilePlugin.profiles.clear() - localProfilePlugin.numOfProfiles = 0 - val singleProfile = LocalProfilePlugin.SingleProfile().copyFrom(localProfilePlugin.rawProfile, profile, "TestProfile") - localProfilePlugin.addProfile(singleProfile) - val profileSwitch = profileFunction.prepareProfileSwitch(localProfilePlugin.createProfileStore(), "TestProfile", 0, 100, 0, dateUtil._now()) - treatmentsPlugin.addToHistoryProfileSwitch(profileSwitch) - // Insulin - configBuilderPlugin.performPluginSwitch(insulinOrefUltraRapidActingPlugin, true, PluginType.INSULIN) - // Pump - sp.putInt(R.string.key_danar_password, R_PASSWORD) - sp.putString(R.string.key_danar_bt_name, R_SERIAL) - configBuilderPlugin.performPluginSwitch((pump as PluginBase), true, PluginType.PUMP) - // Sensitivity - configBuilderPlugin.performPluginSwitch(sensitivityOref1Plugin, true, PluginType.SENSITIVITY) - // APS - configBuilderPlugin.performPluginSwitch(openAPSSMBPlugin, true, PluginType.APS) - configBuilderPlugin.performPluginSwitch(loopPlugin, true, PluginType.LOOP) - - // Enable common - configBuilderPlugin.performPluginSwitch(actionsPlugin, true, ) - - // Disable unneeded - MainApp.getPluginsList().remove(objectivesPlugin) - } - - @Test - fun doTest() { - Assert.assertTrue(isRunningTest()) - preparePlugins() - - while (!pump.isInitialized) { - //log.debug("Waiting for initialization") - SystemClock.sleep(1000) + /* + companion object { + const val R_PASSWORD = 1234 + const val R_SERIAL = "PBB00013LR_P" } - while (true) { - //log.debug("Tick") - SystemClock.sleep(1000) + private val validProfile = "{\"dia\":\"6\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"10\"},{\"time\":\"2:00\",\"value\":\"11\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" + + @Inject lateinit var pump : info.nightscout.androidaps.danaRv2.DanaRv2Plugin + @Inject lateinit var randomBgPlugin :RandomBgPlugin + @Inject lateinit var localProfilePlugin: LocalProfilePlugin + @Inject lateinit var profileFunction: ProfileFunction + @Inject lateinit var insulinOrefUltraRapidActingPlugin: InsulinOrefUltraRapidActingPlugin + @Inject lateinit var sensitivityOref1Plugin: SensitivityOref1Plugin + @Inject lateinit var openAPSSMBPlugin: OpenAPSSMBPlugin + @Inject lateinit var loopPlugin: LoopPlugin + @Inject lateinit var actionsPlugin: ActionsPlugin + @Inject lateinit var configBuilderPlugin: ConfigBuilderPlugin + @Inject lateinit var objectivesPlugin: ObjectivesPlugin + @Inject lateinit var treatmentsPlugin: TreatmentsPlugin + @Inject lateinit var sp: SP + + @Rule + @JvmField + var mActivityTestRule = ActivityTestRule(MainActivity::class.java) + + @Rule + @JvmField + var mGrantPermissionRule: GrantPermissionRule = + GrantPermissionRule.grant( + android.Manifest.permission.ACCESS_FINE_LOCATION, + android.Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, + android.Manifest.permission.WRITE_EXTERNAL_STORAGE + ) + + @Before + fun clear() { + sp.clear() + sp.putBoolean(R.string.key_setupwizard_processed, true) + sp.putString(R.string.key_aps_mode, "closed") + MainApp.getDbHelper().resetDatabases() + MainApp.devBranch = false } - } - */ + + private fun preparePlugins() { + // Source + configBuilderPlugin.performPluginSwitch(randomBgPlugin,true, PluginType.BGSOURCE) + // Profile + configBuilderPlugin.performPluginSwitch(localProfilePlugin, true, PluginType.PROFILE) + val profile = Profile(JSONObject(validProfile), Constants.MGDL) + Assert.assertTrue(profile.isValid("Test")) + localProfilePlugin.profiles.clear() + localProfilePlugin.numOfProfiles = 0 + val singleProfile = LocalProfilePlugin.SingleProfile().copyFrom(localProfilePlugin.rawProfile, profile, "TestProfile") + localProfilePlugin.addProfile(singleProfile) + val profileSwitch = profileFunction.prepareProfileSwitch(localProfilePlugin.createProfileStore(), "TestProfile", 0, 100, 0, dateUtil._now()) + treatmentsPlugin.addToHistoryProfileSwitch(profileSwitch) + // Insulin + configBuilderPlugin.performPluginSwitch(insulinOrefUltraRapidActingPlugin, true, PluginType.INSULIN) + // Pump + sp.putInt(R.string.key_danar_password, R_PASSWORD) + sp.putString(R.string.key_danar_bt_name, R_SERIAL) + configBuilderPlugin.performPluginSwitch((pump as PluginBase), true, PluginType.PUMP) + // Sensitivity + configBuilderPlugin.performPluginSwitch(sensitivityOref1Plugin, true, PluginType.SENSITIVITY) + // APS + configBuilderPlugin.performPluginSwitch(openAPSSMBPlugin, true, PluginType.APS) + configBuilderPlugin.performPluginSwitch(loopPlugin, true, PluginType.LOOP) + + // Enable common + configBuilderPlugin.performPluginSwitch(actionsPlugin, true, ) + + // Disable unneeded + MainApp.getPluginsList().remove(objectivesPlugin) + } + + @Test + fun doTest() { + Assert.assertTrue(isRunningTest()) + preparePlugins() + + while (!pump.isInitialized) { + //log.debug("Waiting for initialization") + SystemClock.sleep(1000) + } + + while (true) { + //log.debug("Tick") + SystemClock.sleep(1000) + } + } + */ } \ No newline at end of file diff --git a/app/src/androidTest/java/info/nightscout/androidaps/SetupWizardActivityTest.kt b/app/src/androidTest/java/info/nightscout/androidaps/SetupWizardActivityTest.kt index ba6a794cab..d5efa1841c 100644 --- a/app/src/androidTest/java/info/nightscout/androidaps/SetupWizardActivityTest.kt +++ b/app/src/androidTest/java/info/nightscout/androidaps/SetupWizardActivityTest.kt @@ -1,195 +1,191 @@ package info.nightscout.androidaps -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.filters.LargeTest -import org.junit.runner.RunWith - -@LargeTest -@RunWith(AndroidJUnit4::class) +//@LargeTest +//@RunWith(AndroidJUnit4::class) class SetupWizardActivityTest { -/* - @Rule - @JvmField - var mActivityTestRule = ActivityTestRule(SetupWizardActivity::class.java) + /* + @Rule + @JvmField + var mActivityTestRule = ActivityTestRule(SetupWizardActivity::class.java) - @Rule - @JvmField - var mGrantPermissionRule: GrantPermissionRule = - GrantPermissionRule.grant( - android.Manifest.permission.ACCESS_FINE_LOCATION, - android.Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, - android.Manifest.permission.WRITE_EXTERNAL_STORAGE - ) + @Rule + @JvmField + var mGrantPermissionRule: GrantPermissionRule = + GrantPermissionRule.grant( + android.Manifest.permission.ACCESS_FINE_LOCATION, + android.Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, + android.Manifest.permission.WRITE_EXTERNAL_STORAGE + ) - @Before - fun clear() { - sp.clear() - } -/* - -To run from command line -gradlew connectedFullDebugAndroidTest - -do not run when your production phone is connected !!! - -do this before for running in emulator -adb shell settings put global window_animation_scale 0 & -adb shell settings put global transition_animation_scale 0 & -adb shell settings put global animator_duration_scale 0 & - */ - - @Test - fun setupWizardActivityTest() { - sp.clear() - Assert.assertTrue(isRunningTest()) - // Welcome page - onView(withId(R.id.next_button)).perform(click()) - // Language selection - onView(withText("English")).perform(scrollTo(), click()) - onView(withId(R.id.next_button)).waitAndPerform(click()) - // Agreement page - onView(withText("I UNDERSTAND AND AGREE")).perform(scrollTo(), click()) - onView(withId(R.id.next_button)).waitAndPerform(click()) - // Location permission - var askButton = onView(withText("Ask for permission")) - if (askButton.isDisplayed()) { - askButton.perform(scrollTo(), click()) - onView(withId(R.id.next_button)).waitAndPerform(click()) + @Before + fun clear() { + sp.clear() } - // Store permission - askButton = onView(withText("Ask for permission")) - if (askButton.isDisplayed()) { - askButton.perform(scrollTo(), click()) - onView(withText("OK")).perform(click()) + /* + + To run from command line + gradlew connectedFullDebugAndroidTest + + do not run when your production phone is connected !!! + + do this before for running in emulator + adb shell settings put global window_animation_scale 0 & + adb shell settings put global transition_animation_scale 0 & + adb shell settings put global animator_duration_scale 0 & + */ + + @Test + fun setupWizardActivityTest() { + sp.clear() + Assert.assertTrue(isRunningTest()) + // Welcome page + onView(withId(R.id.next_button)).perform(click()) + // Language selection + onView(withText("English")).perform(scrollTo(), click()) onView(withId(R.id.next_button)).waitAndPerform(click()) - } - // Import settings : skip of found - askButton = onView(withText("IMPORT SETTINGS")) - if (askButton.isDisplayed()) { + // Agreement page + onView(withText("I UNDERSTAND AND AGREE")).perform(scrollTo(), click()) onView(withId(R.id.next_button)).waitAndPerform(click()) - } - // Units selection - onView(withText("mmol/L")).perform(scrollTo(), click()) - onView(withId(R.id.next_button)).perform(click()) - // Display target selection - onView(withText("4.2")).perform(scrollTo(), ViewActions.replaceText("5")) - onView(withText("10.0")).perform(scrollTo(), ViewActions.replaceText("11")) - onView(withId(R.id.next_button)).perform(click()) - // NSClient - onView(withId(R.id.next_button)).perform(click()) - // Age selection - onView(withText("Adult")).perform(scrollTo(), click()) - onView(withId(R.id.next_button)).waitAndPerform(click()) - // Insulin selection - onView(withText("Ultra-Rapid Oref")).perform(scrollTo(), click()) - onView(withId(R.id.next_button)).waitAndPerform(click()) - // BG source selection - onView(withText("Random BG")).perform(scrollTo(), click()) - onView(withId(R.id.next_button)).waitAndPerform(click()) - // Profile selection - onView(withText("Local Profile")).perform(scrollTo(), click()) - onView(withId(R.id.next_button)).waitAndPerform(click()) - // Local profile - DIA - onView(withTagValue(Matchers.`is`("LP_DIA"))).perform(scrollTo(), ViewActions.replaceText("6.0")) - // Local profile - IC - onView(withId(R.id.ic_tab)).perform(scrollTo(), click()) - onView(Matchers.allOf(withTagValue(Matchers.`is`("IC-1-0")), isDisplayed())) - .perform(ViewActions.replaceText("2"), ViewActions.closeSoftKeyboard()) - // Local profile - ISF - onView(withId(R.id.isf_tab)).perform(scrollTo(), click()) - onView(Matchers.allOf(withTagValue(Matchers.`is`("ISF-1-0")), isDisplayed())) - .perform(ViewActions.replaceText("3"), ViewActions.closeSoftKeyboard()) - // Local profile - BAS - onView(withId(R.id.basal_tab)).perform(scrollTo(), click()) - onView(childAtPosition(Matchers.allOf(withId(R.id.localprofile_basal), childAtPosition(withClassName(Matchers.`is`("android.widget.LinearLayout")), 6)), 2)) - .perform(scrollTo(), click()) - onView(Matchers.allOf(withTagValue(Matchers.`is`("BASAL-1-0")), isDisplayed())) - .perform(ViewActions.replaceText("1.1"), ViewActions.closeSoftKeyboard()) - onView(Matchers.allOf(withTagValue(Matchers.`is`("BASAL-1-1")), isDisplayed())) - .perform(ViewActions.replaceText("1.2"), ViewActions.closeSoftKeyboard()) - onView(Matchers.allOf(withId(R.id.timelistedit_time), childAtPosition(childAtPosition(withId(R.id.localprofile_basal), 2), 0))) - .perform(scrollTo(), click()) - onData(Matchers.anything()).inAdapterView(childAtPosition(withClassName(Matchers.`is`("android.widget.PopupWindow\$PopupBackgroundView")), 0)).atPosition(13) - .perform(click()) - // Local profile - TARGET - onView(withId(R.id.target_tab)).perform(scrollTo(), click()) - onView(Matchers.allOf(withTagValue(Matchers.`is`("TARGET-1-0")), isDisplayed())) - .perform(ViewActions.replaceText("6"), ViewActions.closeSoftKeyboard()) - onView(Matchers.allOf(withTagValue(Matchers.`is`("TARGET-2-0")), isDisplayed())) - .perform(ViewActions.replaceText("6.5"), ViewActions.closeSoftKeyboard()) - onView(withText("Save")).perform(scrollTo(), click()) - onView(Matchers.allOf(withId(R.id.localprofile_profileswitch), isDisplayed())) - .perform(scrollTo(), click()) - onView(allOf(withId(R.id.ok), isDisplayed())).perform(click()) - // confirm dialog - //onView(Matchers.allOf(withText("OK"), isDisplayed())).perform(click()) not working on real phone - clickOkInDialog() - onView(withId(R.id.next_button)).waitAndPerform(click()) - // Profile switch - askButton = onView(withText("Do Profile Switch")) - if (askButton.isDisplayed()) { - askButton.perform(scrollTo(), click()) + // Location permission + var askButton = onView(withText("Ask for permission")) + if (askButton.isDisplayed()) { + askButton.perform(scrollTo(), click()) + onView(withId(R.id.next_button)).waitAndPerform(click()) + } + // Store permission + askButton = onView(withText("Ask for permission")) + if (askButton.isDisplayed()) { + askButton.perform(scrollTo(), click()) + onView(withText("OK")).perform(click()) + onView(withId(R.id.next_button)).waitAndPerform(click()) + } + // Import settings : skip of found + askButton = onView(withText("IMPORT SETTINGS")) + if (askButton.isDisplayed()) { + onView(withId(R.id.next_button)).waitAndPerform(click()) + } + // Units selection + onView(withText("mmol/L")).perform(scrollTo(), click()) + onView(withId(R.id.next_button)).perform(click()) + // Display target selection + onView(withText("4.2")).perform(scrollTo(), ViewActions.replaceText("5")) + onView(withText("10.0")).perform(scrollTo(), ViewActions.replaceText("11")) + onView(withId(R.id.next_button)).perform(click()) + // NSClient + onView(withId(R.id.next_button)).perform(click()) + // Age selection + onView(withText("Adult")).perform(scrollTo(), click()) + onView(withId(R.id.next_button)).waitAndPerform(click()) + // Insulin selection + onView(withText("Ultra-Rapid Oref")).perform(scrollTo(), click()) + onView(withId(R.id.next_button)).waitAndPerform(click()) + // BG source selection + onView(withText("Random BG")).perform(scrollTo(), click()) + onView(withId(R.id.next_button)).waitAndPerform(click()) + // Profile selection + onView(withText("Local Profile")).perform(scrollTo(), click()) + onView(withId(R.id.next_button)).waitAndPerform(click()) + // Local profile - DIA + onView(withTagValue(Matchers.`is`("LP_DIA"))).perform(scrollTo(), ViewActions.replaceText("6.0")) + // Local profile - IC + onView(withId(R.id.ic_tab)).perform(scrollTo(), click()) + onView(Matchers.allOf(withTagValue(Matchers.`is`("IC-1-0")), isDisplayed())) + .perform(ViewActions.replaceText("2"), ViewActions.closeSoftKeyboard()) + // Local profile - ISF + onView(withId(R.id.isf_tab)).perform(scrollTo(), click()) + onView(Matchers.allOf(withTagValue(Matchers.`is`("ISF-1-0")), isDisplayed())) + .perform(ViewActions.replaceText("3"), ViewActions.closeSoftKeyboard()) + // Local profile - BAS + onView(withId(R.id.basal_tab)).perform(scrollTo(), click()) + onView(childAtPosition(Matchers.allOf(withId(R.id.localprofile_basal), childAtPosition(withClassName(Matchers.`is`("android.widget.LinearLayout")), 6)), 2)) + .perform(scrollTo(), click()) + onView(Matchers.allOf(withTagValue(Matchers.`is`("BASAL-1-0")), isDisplayed())) + .perform(ViewActions.replaceText("1.1"), ViewActions.closeSoftKeyboard()) + onView(Matchers.allOf(withTagValue(Matchers.`is`("BASAL-1-1")), isDisplayed())) + .perform(ViewActions.replaceText("1.2"), ViewActions.closeSoftKeyboard()) + onView(Matchers.allOf(withId(R.id.timelistedit_time), childAtPosition(childAtPosition(withId(R.id.localprofile_basal), 2), 0))) + .perform(scrollTo(), click()) + onData(Matchers.anything()).inAdapterView(childAtPosition(withClassName(Matchers.`is`("android.widget.PopupWindow\$PopupBackgroundView")), 0)).atPosition(13) + .perform(click()) + // Local profile - TARGET + onView(withId(R.id.target_tab)).perform(scrollTo(), click()) + onView(Matchers.allOf(withTagValue(Matchers.`is`("TARGET-1-0")), isDisplayed())) + .perform(ViewActions.replaceText("6"), ViewActions.closeSoftKeyboard()) + onView(Matchers.allOf(withTagValue(Matchers.`is`("TARGET-2-0")), isDisplayed())) + .perform(ViewActions.replaceText("6.5"), ViewActions.closeSoftKeyboard()) + onView(withText("Save")).perform(scrollTo(), click()) + onView(Matchers.allOf(withId(R.id.localprofile_profileswitch), isDisplayed())) + .perform(scrollTo(), click()) onView(allOf(withId(R.id.ok), isDisplayed())).perform(click()) - // onView(Matchers.allOf(withText("OK"), isDisplayed())).perform(click()) not working on real phone + // confirm dialog + //onView(Matchers.allOf(withText("OK"), isDisplayed())).perform(click()) not working on real phone clickOkInDialog() - while (ProfileFunctions.getInstance().profile == null) SystemClock.sleep(100) onView(withId(R.id.next_button)).waitAndPerform(click()) - } - // Pump - onView(withText("Virtual Pump")).perform(scrollTo(), click()) - onView(withId(R.id.next_button)).waitAndPerform(click()) - // APS - onView(withText("OpenAPS SMB")).perform(scrollTo(), click()) - onView(withId(R.id.next_button)).waitAndPerform(click()) - // Open Closed Loop - onView(withText("Closed Loop")).perform(scrollTo(), click()) - onView(withId(R.id.next_button)).waitAndPerform(click()) - // Loop - askButton = onView(withText("Enable loop")) - if (askButton.isDisplayed()) { - askButton.perform(scrollTo(), click()) - onView(withId(R.id.next_button)).waitAndPerform(click()) - } - // Sensitivity - onView(withText("Sensitivity Oref1")).perform(scrollTo(), click()) - onView(withId(R.id.next_button)).waitAndPerform(click()) - // Objectives - onView(allOf(withText("Start"), isDisplayed())).perform(scrollTo(), click()) - onView(withId(R.id.finish_button)).waitAndPerform(click()) - - // Verify settings - Assert.assertEquals(Constants.MMOL, ProfileFunctions.getSystemUnits()) - Assert.assertEquals(17.0, HardLimits.maxBolus(), 0.0001) // Adult - Assert.assertTrue(RandomBgPlugin.isEnabled(PluginType.BGSOURCE)) - Assert.assertTrue(LocalProfilePlugin.isEnabled(PluginType.PROFILE)) - val p = ProfileFunctions.getInstance().profile - Assert.assertNotNull(p) - Assert.assertEquals(2.0, p!!.ic, 0.0001) - Assert.assertEquals(3.0 * Constants.MMOLL_TO_MGDL, p.isfMgdl, 0.0001) - Assert.assertEquals(1.1, p.getBasalTimeFromMidnight(0), 0.0001) - Assert.assertEquals(6.0 * Constants.MMOLL_TO_MGDL, p.targetLowMgdl, 0.0001) - Assert.assertTrue(VirtualPumpPlugin.getPlugin().isEnabled(PluginType.PUMP)) - Assert.assertTrue(OpenAPSSMBPlugin.getPlugin().isEnabled()) - Assert.assertTrue(LoopPlugin.getPlugin().isEnabled(PluginType.LOOP)) - Assert.assertTrue(SensitivityOref1Plugin.getPlugin().isEnabled(PluginType.SENSITIVITY)) - Assert.assertTrue(ObjectivesPlugin.objectives[0].isStarted) - } - - private fun childAtPosition( - parentMatcher: Matcher, position: Int): Matcher { - - return object : TypeSafeMatcher() { - override fun describeTo(description: Description) { - description.appendText("Child at position $position in parent ") - parentMatcher.describeTo(description) + // Profile switch + askButton = onView(withText("Do Profile Switch")) + if (askButton.isDisplayed()) { + askButton.perform(scrollTo(), click()) + onView(allOf(withId(R.id.ok), isDisplayed())).perform(click()) + // onView(Matchers.allOf(withText("OK"), isDisplayed())).perform(click()) not working on real phone + clickOkInDialog() + while (ProfileFunctions.getInstance().profile == null) SystemClock.sleep(100) + onView(withId(R.id.next_button)).waitAndPerform(click()) } + // Pump + onView(withText("Virtual Pump")).perform(scrollTo(), click()) + onView(withId(R.id.next_button)).waitAndPerform(click()) + // APS + onView(withText("OpenAPS SMB")).perform(scrollTo(), click()) + onView(withId(R.id.next_button)).waitAndPerform(click()) + // Open Closed Loop + onView(withText("Closed Loop")).perform(scrollTo(), click()) + onView(withId(R.id.next_button)).waitAndPerform(click()) + // Loop + askButton = onView(withText("Enable loop")) + if (askButton.isDisplayed()) { + askButton.perform(scrollTo(), click()) + onView(withId(R.id.next_button)).waitAndPerform(click()) + } + // Sensitivity + onView(withText("Sensitivity Oref1")).perform(scrollTo(), click()) + onView(withId(R.id.next_button)).waitAndPerform(click()) + // Objectives + onView(allOf(withText("Start"), isDisplayed())).perform(scrollTo(), click()) + onView(withId(R.id.finish_button)).waitAndPerform(click()) - public override fun matchesSafely(view: View): Boolean { - val parent = view.parent - return parent is ViewGroup && parentMatcher.matches(parent) - && view == parent.getChildAt(position) + // Verify settings + Assert.assertEquals(Constants.MMOL, ProfileFunctions.getSystemUnits()) + Assert.assertEquals(17.0, HardLimits.maxBolus(), 0.0001) // Adult + Assert.assertTrue(RandomBgPlugin.isEnabled(PluginType.BGSOURCE)) + Assert.assertTrue(LocalProfilePlugin.isEnabled(PluginType.PROFILE)) + val p = ProfileFunctions.getInstance().profile + Assert.assertNotNull(p) + Assert.assertEquals(2.0, p!!.ic, 0.0001) + Assert.assertEquals(3.0 * Constants.MMOLL_TO_MGDL, p.isfMgdl, 0.0001) + Assert.assertEquals(1.1, p.getBasalTimeFromMidnight(0), 0.0001) + Assert.assertEquals(6.0 * Constants.MMOLL_TO_MGDL, p.targetLowMgdl, 0.0001) + Assert.assertTrue(VirtualPumpPlugin.getPlugin().isEnabled(PluginType.PUMP)) + Assert.assertTrue(OpenAPSSMBPlugin.getPlugin().isEnabled()) + Assert.assertTrue(LoopPlugin.getPlugin().isEnabled(PluginType.LOOP)) + Assert.assertTrue(SensitivityOref1Plugin.getPlugin().isEnabled(PluginType.SENSITIVITY)) + Assert.assertTrue(ObjectivesPlugin.objectives[0].isStarted) + } + + private fun childAtPosition( + parentMatcher: Matcher, position: Int): Matcher { + + return object : TypeSafeMatcher() { + override fun describeTo(description: Description) { + description.appendText("Child at position $position in parent ") + parentMatcher.describeTo(description) + } + + public override fun matchesSafely(view: View): Boolean { + val parent = view.parent + return parent is ViewGroup && parentMatcher.matches(parent) + && view == parent.getChildAt(position) + } } } - } - */ + */ } diff --git a/app/src/main/java/info/nightscout/androidaps/MainActivity.kt b/app/src/main/java/info/nightscout/androidaps/MainActivity.kt index 9adbcafd07..ffc876d687 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/MainActivity.kt @@ -52,7 +52,7 @@ import info.nightscout.database.entities.UserEntry.Sources import info.nightscout.interfaces.AndroidPermission import info.nightscout.interfaces.Config 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.maintenance.PrefFileListProvider import info.nightscout.interfaces.plugin.ActivePlugin @@ -96,7 +96,7 @@ class MainActivity : DaggerAppCompatActivityWithResult() { @Inject lateinit var fabricPrivacy: FabricPrivacy @Inject lateinit var protectionCheck: ProtectionCheck @Inject lateinit var iconsProvider: IconsProvider - @Inject lateinit var constraintChecker: Constraints + @Inject lateinit var constraintChecker: ConstraintsChecker @Inject lateinit var signatureVerifierPlugin: SignatureVerifierPlugin @Inject lateinit var uel: UserEntryLogger @Inject lateinit var profileFunction: ProfileFunction diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.kt b/app/src/main/java/info/nightscout/androidaps/MainApp.kt index 67b544ed75..3c3e6b1a9a 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainApp.kt +++ b/app/src/main/java/info/nightscout/androidaps/MainApp.kt @@ -38,6 +38,7 @@ import info.nightscout.interfaces.notifications.Notification import info.nightscout.interfaces.plugin.PluginBase import info.nightscout.interfaces.ui.UiInteraction 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.themes.ThemeSwitcherPlugin import info.nightscout.rx.logging.AAPSLogger @@ -77,7 +78,7 @@ class MainApp : DaggerApplication() { @Inject lateinit var compatDBHelper: CompatDBHelper @Inject lateinit var repository: AppRepository @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 uiInteraction: UiInteraction @Inject lateinit var notificationStore: NotificationStore diff --git a/app/src/main/java/info/nightscout/androidaps/di/ServicesModule.kt b/app/src/main/java/info/nightscout/androidaps/di/ServicesModule.kt deleted file mode 100644 index 200b83579f..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/di/ServicesModule.kt +++ /dev/null @@ -1,2 +0,0 @@ -package info.nightscout.androidaps.di - diff --git a/app/src/test/java/info/nightscout/plugins/aps/loop/LoopPluginTest.kt b/app/src/test/java/info/nightscout/plugins/aps/loop/LoopPluginTest.kt index 7f74063515..69c9d56b79 100644 --- a/app/src/test/java/info/nightscout/plugins/aps/loop/LoopPluginTest.kt +++ b/app/src/test/java/info/nightscout/plugins/aps/loop/LoopPluginTest.kt @@ -8,8 +8,7 @@ import info.nightscout.core.utils.fabric.FabricPrivacy import info.nightscout.database.impl.AppRepository import info.nightscout.interfaces.ApsMode import info.nightscout.interfaces.Config -import info.nightscout.sdk.interfaces.RunningConfiguration -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.iob.IobCobCalculator import info.nightscout.interfaces.logging.UserEntryLogger 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.ui.UiInteraction 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.sharedPreferences.SP import info.nightscout.shared.utils.DateUtil @@ -34,8 +33,7 @@ import org.mockito.Mockito.`when` class LoopPluginTest : TestBase() { @Mock lateinit var sp: SP - private val rxBus: RxBus = RxBus(aapsSchedulers, aapsLogger) - @Mock lateinit var constraintChecker: Constraints + @Mock lateinit var constraintChecker: ConstraintsChecker @Mock lateinit var rh: ResourceHelper @Mock lateinit var profileFunction: ProfileFunction @Mock lateinit var context: Context diff --git a/app/src/test/java/info/nightscout/plugins/configBuilder/ConfigBuilderPluginTest.kt b/app/src/test/java/info/nightscout/plugins/configBuilder/ConfigBuilderPluginTest.kt index 3013ce8090..3061e18835 100644 --- a/app/src/test/java/info/nightscout/plugins/configBuilder/ConfigBuilderPluginTest.kt +++ b/app/src/test/java/info/nightscout/plugins/configBuilder/ConfigBuilderPluginTest.kt @@ -8,7 +8,6 @@ import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.protection.ProtectionCheck import info.nightscout.interfaces.pump.PumpSync import info.nightscout.interfaces.ui.UiInteraction -import info.nightscout.rx.bus.RxBus import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.sharedPreferences.SP import info.nightscout.sharedtests.TestBase @@ -37,6 +36,6 @@ class ConfigBuilderPluginTest : TestBase() { @BeforeEach 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) } } \ No newline at end of file diff --git a/app/src/test/java/info/nightscout/plugins/constraints/ConstraintsCheckerTest.kt b/app/src/test/java/info/nightscout/plugins/constraints/ConstraintsCheckerTest.kt index ad5bac6590..627ff00b5e 100644 --- a/app/src/test/java/info/nightscout/plugins/constraints/ConstraintsCheckerTest.kt +++ b/app/src/test/java/info/nightscout/plugins/constraints/ConstraintsCheckerTest.kt @@ -9,13 +9,14 @@ import info.nightscout.androidaps.insight.database.InsightDatabase import info.nightscout.androidaps.insight.database.InsightDatabaseDao import info.nightscout.androidaps.insight.database.InsightDbHelper import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.database.impl.AppRepository import info.nightscout.implementation.iob.GlucoseStatusProviderImpl import info.nightscout.interfaces.ApsMode import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints import info.nightscout.interfaces.constraints.Objectives +import info.nightscout.interfaces.constraints.PluginConstraints import info.nightscout.interfaces.maintenance.PrefFileListProvider import info.nightscout.interfaces.plugin.PluginBase import info.nightscout.interfaces.plugin.PluginType @@ -74,7 +75,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() { private lateinit var danaPump: DanaPump private lateinit var insightDbHelper: InsightDbHelper - private lateinit var constraintChecker: ConstraintsImpl + private lateinit var constraintChecker: ConstraintsCheckerImpl private lateinit var safetyPlugin: SafetyPlugin private lateinit var objectivesPlugin: ObjectivesPlugin private lateinit var comboPlugin: ComboPlugin @@ -94,6 +95,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() { if (it is PumpEnactResult) { 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("") //SafetyPlugin - constraintChecker = ConstraintsImpl(activePlugin) + constraintChecker = ConstraintsCheckerImpl(activePlugin, injector) val glucoseStatusProvider = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculator, dateUtil, decimalFormatter) @@ -226,7 +230,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() { constraintsPluginsList.add(insightPlugin) constraintsPluginsList.add(openAPSAMAPlugin) constraintsPluginsList.add(openAPSSMBPlugin) - `when`(activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)).thenReturn(constraintsPluginsList) + `when`(activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)).thenReturn(constraintsPluginsList) objectivesPlugin.onStart() } @@ -268,7 +272,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() { val c = constraintChecker.isAutosensModeEnabled() assertThat(c.reasonList).hasSize(2) // Safety & Objectives assertThat(c.mostLimitedReasonList).hasSize(2) // Safety & Objectives - assertThat( c.value()).isFalse() + assertThat(c.value()).isFalse() } // Safety @@ -278,7 +282,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() { val c = constraintChecker.isAdvancedFilteringEnabled() assertThat(c.reasonList).hasSize(1) // Safety assertThat(c.mostLimitedReasonList).hasSize(1) // Safety - assertThat( c.value()).isFalse() + assertThat(c.value()).isFalse() } // SMB should limit @@ -286,7 +290,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() { fun isSuperBolusEnabledTest() { openAPSSMBPlugin.setPluginEnabled(PluginType.APS, true) val c = constraintChecker.isSuperBolusEnabled() - assertThat( c.value()).isFalse() // SMB should limit + assertThat(c.value()).isFalse() // SMB should limit } // Safety & Objectives @@ -296,11 +300,11 @@ class ConstraintsCheckerTest : TestBaseWithProfile() { objectivesPlugin.objectives[Objectives.SMB_OBJECTIVE].startedOn = 0 `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`(constraintChecker.isClosedLoopAllowed()).thenReturn(Constraint(true)) +// `when`(constraintChecker.isClosedLoopAllowed()).thenReturn(ConstraintObject(true)) val c = constraintChecker.isSMBModeEnabled() assertThat(c.reasonList).hasSize(3) // 2x Safety & Objectives assertThat(c.mostLimitedReasonList).hasSize(3) // 2x Safety & Objectives - assertThat( c.value()).isFalse() + assertThat(c.value()).isFalse() } // applyBasalConstraints tests @@ -326,9 +330,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() { // Apply all limits 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.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 @@ -355,7 +359,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() { val i = constraintChecker.getMaxBasalPercentAllowed(validProfile) assertThat(i.value()).isEqualTo(200) 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 @@ -380,9 +384,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() { // Apply all limits 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.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 @@ -395,7 +399,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() { val i = constraintChecker.getMaxCarbsAllowed() assertThat(i.value()).isEqualTo(48) 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 @@ -410,9 +414,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() { // Apply all limits 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.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 @@ -426,8 +430,8 @@ class ConstraintsCheckerTest : TestBaseWithProfile() { // Apply all limits 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.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") } } diff --git a/app/src/test/java/info/nightscout/plugins/safety/SafetyPluginTest.kt b/app/src/test/java/info/nightscout/plugins/safety/SafetyPluginTest.kt index 56e88846d8..d473e1c789 100644 --- a/app/src/test/java/info/nightscout/plugins/safety/SafetyPluginTest.kt +++ b/app/src/test/java/info/nightscout/plugins/safety/SafetyPluginTest.kt @@ -3,12 +3,12 @@ package info.nightscout.plugins.safety import com.google.common.truth.Truth.assertThat import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.database.impl.AppRepository import info.nightscout.interfaces.ApsMode -import info.nightscout.interfaces.Constants import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.iob.GlucoseStatusProvider import info.nightscout.interfaces.plugin.PluginType import info.nightscout.interfaces.profiling.Profiler @@ -29,7 +29,7 @@ import org.mockito.Mockito.`when` class SafetyPluginTest : TestBaseWithProfile() { - @Mock lateinit var constraintChecker: Constraints + @Mock lateinit var constraintChecker: ConstraintsChecker @Mock lateinit var virtualPumpPlugin: VirtualPumpPlugin @Mock lateinit var glimpPlugin: GlimpPlugin @Mock lateinit var profiler: Profiler @@ -43,7 +43,13 @@ class SafetyPluginTest : TestBaseWithProfile() { private lateinit var openAPSAMAPlugin: OpenAPSAMAPlugin 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() @BeforeEach @@ -86,9 +92,8 @@ class SafetyPluginTest : TestBaseWithProfile() { @Test fun pumpDescriptionShouldLimitLoopInvocation() { pumpDescription.isTempBasalCapable = false - var c = Constraint(true) - c = safetyPlugin.isLoopInvocationAllowed(c) - assertThat(c.getReasons(aapsLogger)).isEqualTo("Safety: Pump is not temp basal capable") + val c = safetyPlugin.isLoopInvocationAllowed(ConstraintObject(true, injector)) + assertThat(c.getReasons()).isEqualTo("Safety: Pump is not temp basal capable") assertThat(c.value()).isFalse() } @@ -96,47 +101,42 @@ class SafetyPluginTest : TestBaseWithProfile() { fun disabledEngineeringModeShouldLimitClosedLoop() { `when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.CLOSED.name) `when`(config.isEngineeringModeOrRelease()).thenReturn(false) - var c = Constraint(true) - c = safetyPlugin.isClosedLoopAllowed(c) - assertThat(c.getReasons(aapsLogger)).contains("Running dev version. Closed loop is disabled.") + val c = safetyPlugin.isClosedLoopAllowed(ConstraintObject(true, injector)) + assertThat(c.getReasons()).contains("Running dev version. Closed loop is disabled.") assertThat(c.value()).isFalse() } @Test fun setOpenLoopInPreferencesShouldLimitClosedLoop() { `when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.OPEN.name) - var c = Constraint(true) - c = safetyPlugin.isClosedLoopAllowed(c) - assertThat(c.getReasons(aapsLogger)).contains("Closed loop mode disabled in preferences") + val c = safetyPlugin.isClosedLoopAllowed(ConstraintObject(true, injector)) + assertThat(c.getReasons()).contains("Closed loop mode disabled in preferences") assertThat(c.value()).isFalse() } @Test fun notEnabledSMBInPreferencesDisablesSMB() { `when`(sp.getBoolean(info.nightscout.plugins.aps.R.string.key_use_smb, false)).thenReturn(false) - `when`(constraintChecker.isClosedLoopAllowed(anyObject())).thenReturn(Constraint(true)) - var c = Constraint(true) - c = openAPSSMBPlugin.isSMBModeEnabled(c) - assertThat(c.getReasons(aapsLogger)).contains("SMB disabled in preferences") + `when`(constraintChecker.isClosedLoopAllowed(anyObject())).thenReturn(ConstraintObject(true, injector)) + val c = openAPSSMBPlugin.isSMBModeEnabled(ConstraintObject(true, injector)) + assertThat(c.getReasons()).contains("SMB disabled in preferences") assertThat(c.value()).isFalse() } @Test fun openLoopPreventsSMB() { `when`(sp.getBoolean(info.nightscout.plugins.aps.R.string.key_use_smb, false)).thenReturn(true) - `when`(constraintChecker.isClosedLoopAllowed(anyObject())).thenReturn(Constraint(false)) - var c = Constraint(true) - c = safetyPlugin.isSMBModeEnabled(c) - assertThat(c.getReasons(aapsLogger)).contains("SMB not allowed in open loop mode") + `when`(constraintChecker.isClosedLoopAllowed()).thenReturn(ConstraintObject(false, injector)) + val c = safetyPlugin.isSMBModeEnabled(ConstraintObject(true, injector)) + assertThat(c.getReasons()).contains("SMB not allowed in open loop mode") assertThat(c.value()).isFalse() } @Test fun bgSourceShouldPreventSMBAlways() { `when`(activePlugin.activeBgSource).thenReturn(glimpPlugin) - var c = Constraint(true) - c = safetyPlugin.isAdvancedFilteringEnabled(c) - assertThat(c.getReasons(aapsLogger)).isEqualTo("Safety: SMB always and after carbs disabled because active BG source doesn\\'t support advanced filtering") + val c = safetyPlugin.isAdvancedFilteringEnabled(ConstraintObject(true, injector)) + assertThat(c.getReasons()).isEqualTo("Safety: SMB always and after carbs disabled because active BG source doesn\\'t support advanced filtering") 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_max_daily_safety_multiplier, 3.0)).thenReturn(3.0) `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) 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 - """.trimIndent()) - assertThat(c.getMostLimitedReasons(aapsLogger)).isEqualTo("Safety: Limiting max basal rate to 2.00 U/h because of hard limit") + """.trimIndent() + ) + assertThat(c.getMostLimitedReasons()).isEqualTo("Safety: Limiting max basal rate to 2.00 U/h because of hard limit") } @Test fun doNotAllowNegativeBasalRate() { `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) assertThat(d.value()).isWithin(0.01).of(0.0) - assertThat(d.getReasons(aapsLogger)).isEqualTo( - "Safety: Limiting max basal rate to 0.00 U/h because of it must be positive value") + assertThat(d.getReasons()).isEqualTo( + "Safety: Limiting max basal rate to 0.00 U/h because of it must be positive value" + ) } @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_max_daily_safety_multiplier, 3.0)).thenReturn(3.0) `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) 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 percent rate to 200% because of pump limit Safety: Limiting max basal rate to 500.00 U/h because of pump limit """.trimIndent() ) - 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" + ) } @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.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child") openAPSSMBPlugin.setPluginEnabled(PluginType.APS, true) - val i = Constraint(Constants.REALLYHIGHBASALRATE) + val i = ConstraintObject(Double.MAX_VALUE, injector) openAPSSMBPlugin.applyBasalConstraints(i, validProfile) 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 4.00 U/h because of max basal multiplier OpenAPSSMB: Limiting max basal rate to 3.00 U/h because of max daily basal multiplier - """.trimIndent()) - assertThat(i.getMostLimitedReasons(aapsLogger)).isEqualTo("OpenAPSSMB: Limiting max basal rate to 1.00 U/h because of max value in preferences") + """.trimIndent() + ) + assertThat(i.getMostLimitedReasons()).isEqualTo("OpenAPSSMB: Limiting max basal rate to 1.00 U/h because of max value in preferences") } @Test fun doNotAllowNegativePercentBasalRate() { `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) 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: Limiting max basal rate to 0.00 U/h because of it must be positive value Safety: Limiting max percent rate to 0% because of pump limit - """.trimIndent()) - assertThat(i.getMostLimitedReasons(aapsLogger)).isEqualTo("Safety: Limiting max percent rate to 0% because of pump limit") + """.trimIndent() + ) + assertThat(i.getMostLimitedReasons()).isEqualTo("Safety: Limiting max percent rate to 0% because of pump limit") } @Test fun bolusAmountShouldBeLimited() { `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") - var d = Constraint(Constants.REALLYHIGHBOLUS) - d = safetyPlugin.applyBolusConstraints(d) + val d = safetyPlugin.applyBolusConstraints(ConstraintObject(Double.MAX_VALUE, injector)) 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 5.0 U because of hard limit - """.trimIndent()) - assertThat(d.getMostLimitedReasons(aapsLogger)).isEqualTo("Safety: Limiting bolus to 3.0 U because of max value in preferences") + """.trimIndent() + ) + assertThat(d.getMostLimitedReasons()).isEqualTo("Safety: Limiting bolus to 3.0 U because of max value in preferences") } @Test fun doNotAllowNegativeBolusAmount() { `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") - var d = Constraint(-22.0) - d = safetyPlugin.applyBolusConstraints(d) + val d = safetyPlugin.applyBolusConstraints(ConstraintObject(-22.0, injector)) 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.getMostLimitedReasons(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()).isEqualTo("Safety: Limiting bolus to 0.0 U because of it must be positive value") } @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) // Negative carbs not allowed - var i = Constraint(-22) + var i: Constraint = ConstraintObject(-22, injector) safetyPlugin.applyCarbsConstraints(i) 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 - i = safetyPlugin.applyCarbsConstraints(Constraint(Constants.REALLYHIGHCARBS)) + i = safetyPlugin.applyCarbsConstraints(ConstraintObject(Int.MAX_VALUE, injector)) 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 @@ -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") // Apply all limits - var d = Constraint(Constants.REALLYHIGHIOB) + var d: Constraint = ConstraintObject(Double.MAX_VALUE, injector) d = safetyPlugin.applyMaxIOBConstraints(d) 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.getMostLimitedReasons(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()).isEqualTo("Safety: Limiting IOB to 0.0 U because of Low Glucose Suspend") // Apply all limits - d = Constraint(Constants.REALLYHIGHIOB) + d = ConstraintObject(Double.MAX_VALUE, injector) val a = openAPSAMAPlugin.applyMaxIOBConstraints(d) 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.getMostLimitedReasons(aapsLogger)).isEqualTo("OpenAPSAMA: Limiting IOB to 1.5 U because of max value in preferences") + 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()).isEqualTo("OpenAPSAMA: Limiting IOB to 1.5 U because of max value in preferences") // Apply all limits - d = Constraint(Constants.REALLYHIGHIOB) + d = ConstraintObject(Double.MAX_VALUE, injector) val s = openAPSSMBPlugin.applyMaxIOBConstraints(d) 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.getMostLimitedReasons(aapsLogger)).isEqualTo("OpenAPSSMB: Limiting IOB to 3.0 U because of max value in preferences") + 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()).isEqualTo("OpenAPSSMB: Limiting IOB to 3.0 U because of max value in preferences") } } diff --git a/core/interfaces/src/main/java/info/nightscout/interfaces/Constants.kt b/core/interfaces/src/main/java/info/nightscout/interfaces/Constants.kt index fccdfcbc8f..e0c3bacd59 100644 --- a/core/interfaces/src/main/java/info/nightscout/interfaces/Constants.kt +++ b/core/interfaces/src/main/java/info/nightscout/interfaces/Constants.kt @@ -10,11 +10,6 @@ object Constants { const val MMOLL_TO_MGDL = 18.0 // 18.0182; const val MGDL_TO_MMOLL = 1 / MMOLL_TO_MGDL 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 // SMS COMMUNICATOR diff --git a/core/interfaces/src/main/java/info/nightscout/interfaces/constraints/Constraint.kt b/core/interfaces/src/main/java/info/nightscout/interfaces/constraints/Constraint.kt index a332b9328d..e508da3fef 100644 --- a/core/interfaces/src/main/java/info/nightscout/interfaces/constraints/Constraint.kt +++ b/core/interfaces/src/main/java/info/nightscout/interfaces/constraints/Constraint.kt @@ -1,115 +1,18 @@ package info.nightscout.interfaces.constraints -import info.nightscout.rx.logging.AAPSLogger -import info.nightscout.rx.logging.LTag - -class Constraint>(private var value: T) { - - private var originalValue: T - private val reasons: MutableList = ArrayList() - private val mostLimiting: MutableList = ArrayList() - fun value(): T { - return value - } - - fun originalValue(): T { - return originalValue - } - - fun set(aapsLogger: AAPSLogger, value: T): Constraint { - 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 { - 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 { - 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 { - 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 { - 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() - } +interface Constraint> { + fun value(): T + fun originalValue(): T + fun set(value: T): Constraint + fun set(value: T, reason: String, from: Any): Constraint + fun setIfDifferent(value: T, reason: String, from: Any): Constraint + fun setIfSmaller(value: T, reason: String, from: Any): Constraint + fun setIfGreater(value: T, reason: String, from: Any): Constraint + fun addReason(reason: String, from: Any) + fun getReasons(): String val reasonList: List - get() = reasons - - 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() - } - + fun getMostLimitedReasons(): String val mostLimitedReasonList: List - get() = mostLimiting - - fun copyReasons(another: Constraint<*>) { - reasons.addAll(another.reasonList) - } - - init { - originalValue = value - } + fun copyReasons(another: Constraint<*>) } \ No newline at end of file diff --git a/core/interfaces/src/main/java/info/nightscout/interfaces/constraints/Constraints.kt b/core/interfaces/src/main/java/info/nightscout/interfaces/constraints/Constraints.kt deleted file mode 100644 index c7ed46d688..0000000000 --- a/core/interfaces/src/main/java/info/nightscout/interfaces/constraints/Constraints.kt +++ /dev/null @@ -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 = Constraint(true)): Constraint = value - fun isClosedLoopAllowed(value: Constraint = Constraint(true)): Constraint = value - fun isLgsAllowed(value: Constraint = Constraint(true)): Constraint = value - fun isAutosensModeEnabled(value: Constraint = Constraint(true)): Constraint = value - fun isSMBModeEnabled(value: Constraint = Constraint(true)): Constraint = value - fun isDynIsfModeEnabled(value: Constraint = Constraint(true)): Constraint = value - fun isUAMEnabled(value: Constraint = Constraint(true)): Constraint = value - fun isAdvancedFilteringEnabled(value: Constraint = Constraint(true)): Constraint = value - fun isSuperBolusEnabled(value: Constraint = Constraint(true)): Constraint = value - fun isAutomationEnabled(value: Constraint = Constraint(true)): Constraint = value - fun applyBasalConstraints(absoluteRate: Constraint, profile: Profile): Constraint = absoluteRate - fun applyBasalPercentConstraints(percentRate: Constraint, profile: Profile): Constraint = percentRate - fun applyBolusConstraints(insulin: Constraint): Constraint = insulin - fun applyExtendedBolusConstraints(insulin: Constraint): Constraint = insulin - fun applyCarbsConstraints(carbs: Constraint): Constraint = carbs - fun applyMaxIOBConstraints(maxIob: Constraint): Constraint = maxIob - - /* - * Determine max values by walking through all constraints - */ - fun getMaxBasalAllowed(profile: Profile): Constraint = - applyBasalConstraints(Constraint(Constants.REALLYHIGHBASALRATE), profile) - - fun getMaxBasalPercentAllowed(profile: Profile): Constraint = - applyBasalPercentConstraints(Constraint(Constants.REALLYHIGHPERCENTBASALRATE), profile) - - fun getMaxBolusAllowed(): Constraint = - applyBolusConstraints(Constraint(Constants.REALLYHIGHBOLUS)) - - fun getMaxExtendedBolusAllowed(): Constraint = - applyExtendedBolusConstraints(Constraint(Constants.REALLYHIGHBOLUS)) - - fun getMaxCarbsAllowed(): Constraint = - applyCarbsConstraints(Constraint(Constants.REALLYHIGHCARBS)) - - fun getMaxIOBAllowed(): Constraint = - applyMaxIOBConstraints(Constraint(Constants.REALLYHIGHIOB)) - - -} \ No newline at end of file diff --git a/core/interfaces/src/main/java/info/nightscout/interfaces/constraints/ConstraintsChecker.kt b/core/interfaces/src/main/java/info/nightscout/interfaces/constraints/ConstraintsChecker.kt new file mode 100644 index 0000000000..c1f3dde85d --- /dev/null +++ b/core/interfaces/src/main/java/info/nightscout/interfaces/constraints/ConstraintsChecker.kt @@ -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 + fun isClosedLoopAllowed(): Constraint + fun isLgsAllowed(): Constraint + fun isAutosensModeEnabled(): Constraint + fun isSMBModeEnabled(): Constraint + fun isDynIsfModeEnabled(): Constraint + fun isUAMEnabled(): Constraint + fun isAdvancedFilteringEnabled(): Constraint + fun isSuperBolusEnabled(): Constraint + fun isAutomationEnabled(): Constraint + + /* + * Determine max values by walking through all constraints + */ + fun getMaxBasalAllowed(profile: Profile): Constraint + fun getMaxBasalPercentAllowed(profile: Profile): Constraint + fun getMaxBolusAllowed(): Constraint + fun getMaxExtendedBolusAllowed(): Constraint + fun getMaxCarbsAllowed(): Constraint + fun getMaxIOBAllowed(): Constraint +} \ No newline at end of file diff --git a/core/interfaces/src/main/java/info/nightscout/interfaces/constraints/PluginConstraints.kt b/core/interfaces/src/main/java/info/nightscout/interfaces/constraints/PluginConstraints.kt new file mode 100644 index 0000000000..abc4cb45e3 --- /dev/null +++ b/core/interfaces/src/main/java/info/nightscout/interfaces/constraints/PluginConstraints.kt @@ -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): Constraint = value + fun isClosedLoopAllowed(value: Constraint): Constraint = value + fun isLgsAllowed(value: Constraint): Constraint = value + fun isAutosensModeEnabled(value: Constraint): Constraint = value + fun isSMBModeEnabled(value: Constraint): Constraint = value + fun isDynIsfModeEnabled(value: Constraint): Constraint = value + fun isUAMEnabled(value: Constraint): Constraint = value + fun isAdvancedFilteringEnabled(value: Constraint): Constraint = value + fun isSuperBolusEnabled(value: Constraint): Constraint = value + fun isAutomationEnabled(value: Constraint): Constraint = value + fun applyBasalConstraints(absoluteRate: Constraint, profile: Profile): Constraint = absoluteRate + fun applyBasalPercentConstraints(percentRate: Constraint, profile: Profile): Constraint = percentRate + fun applyBolusConstraints(insulin: Constraint): Constraint = insulin + fun applyExtendedBolusConstraints(insulin: Constraint): Constraint = insulin + fun applyCarbsConstraints(carbs: Constraint): Constraint = carbs + fun applyMaxIOBConstraints(maxIob: Constraint): Constraint = maxIob +} \ No newline at end of file diff --git a/core/main/build.gradle b/core/main/build.gradle index 4f27351da0..95c63acdde 100644 --- a/core/main/build.gradle +++ b/core/main/build.gradle @@ -20,6 +20,7 @@ dependencies { implementation project(':core:utils') testImplementation project(':app-wear-shared:shared-tests') + testImplementation project(':app-wear-shared:shared-impl') api "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" diff --git a/core/main/src/main/java/info/nightscout/core/constraints/ConstraintObject.kt b/core/main/src/main/java/info/nightscout/core/constraints/ConstraintObject.kt new file mode 100644 index 0000000000..afda3ffa62 --- /dev/null +++ b/core/main/src/main/java/info/nightscout/core/constraints/ConstraintObject.kt @@ -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>(private var value: T, injector: HasAndroidInjector) : Constraint { + + @Inject lateinit var aapsLogger: AAPSLogger + + private var originalValue: T + private val reasons: MutableList = ArrayList() + private val mostLimiting: MutableList = ArrayList() + override fun value(): T { + return value + } + + override fun originalValue(): T { + return originalValue + } + + override fun set(value: T): Constraint { + this.value = value + originalValue = value + aapsLogger.debug(LTag.CONSTRAINTS, "Setting value $value") + return this + } + + override fun set(value: T, reason: String, from: Any): Constraint { + 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 { + 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 { + 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 { + 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 + 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 + get() = mostLimiting + + override fun copyReasons(another: Constraint<*>) { + reasons.addAll(another.reasonList) + } + + init { + injector.androidInjector().inject(this) + originalValue = value + } +} \ No newline at end of file diff --git a/core/main/src/main/java/info/nightscout/core/wizard/BolusWizard.kt b/core/main/src/main/java/info/nightscout/core/wizard/BolusWizard.kt index 3c925fe15b..f623f9681e 100644 --- a/core/main/src/main/java/info/nightscout/core/wizard/BolusWizard.kt +++ b/core/main/src/main/java/info/nightscout/core/wizard/BolusWizard.kt @@ -4,6 +4,7 @@ import android.content.Context import android.text.Spanned import com.google.common.base.Joiner import dagger.android.HasAndroidInjector +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.core.extensions.highValueToUnitsToString import info.nightscout.core.extensions.lowValueToUnitsToString 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.aps.Loop import info.nightscout.interfaces.automation.Automation -import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.db.PersistenceLayer import info.nightscout.interfaces.iob.GlucoseStatus import info.nightscout.interfaces.iob.GlucoseStatusProvider @@ -63,7 +63,7 @@ class BolusWizard @Inject constructor( @Inject lateinit var sp: SP @Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var profileUtil: ProfileUtil - @Inject lateinit var constraintChecker: Constraints + @Inject lateinit var constraintChecker: ConstraintsChecker @Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var commandQueue: CommandQueue @Inject lateinit var loop: Loop @@ -273,7 +273,7 @@ class BolusWizard @Inject constructor( val bolusStep = activePlugin.activePump.pumpDescription.bolusStep calculatedTotalInsulin = Round.roundTo(calculatedTotalInsulin, bolusStep) - insulinAfterConstraints = constraintChecker.applyBolusConstraints(Constraint(calculatedTotalInsulin)).value() + insulinAfterConstraints = constraintChecker.applyBolusConstraints(ConstraintObject(calculatedTotalInsulin, injector)).value() aapsLogger.debug(this.toString()) return this diff --git a/core/main/src/test/java/info/nightscout/core/data/ConstraintTest.kt b/core/main/src/test/java/info/nightscout/core/data/ConstraintTest.kt index 77589bd104..e961021203 100644 --- a/core/main/src/test/java/info/nightscout/core/data/ConstraintTest.kt +++ b/core/main/src/test/java/info/nightscout/core/data/ConstraintTest.kt @@ -1,6 +1,8 @@ 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 org.junit.jupiter.api.Assertions import org.junit.jupiter.api.BeforeEach @@ -11,41 +13,49 @@ import org.junit.jupiter.api.Test */ class ConstraintTest : TestBase() { + private val injector = HasAndroidInjector { + AndroidInjector { + if (it is ConstraintObject<*>) { + it.aapsLogger = aapsLogger + } + } + } + @Test fun doTests() { - val b = Constraint(true) + val b = ConstraintObject(true, injector) Assertions.assertEquals(true, b.value()) - Assertions.assertEquals("", b.getReasons(aapsLogger)) - Assertions.assertEquals("", b.getMostLimitedReasons(aapsLogger)) - b.set(aapsLogger, false) + Assertions.assertEquals("", b.getReasons()) + Assertions.assertEquals("", b.getMostLimitedReasons()) + b.set(false) Assertions.assertEquals(false, b.value()) - Assertions.assertEquals("", b.getReasons(aapsLogger)) - Assertions.assertEquals("", b.getMostLimitedReasons(aapsLogger)) - b.set(aapsLogger, true, "Set true", this) + Assertions.assertEquals("", b.getReasons()) + Assertions.assertEquals("", b.getMostLimitedReasons()) + b.set(true, "Set true", this) Assertions.assertEquals(true, b.value()) - Assertions.assertEquals("ConstraintTest: Set true", b.getReasons(aapsLogger)) - Assertions.assertEquals("ConstraintTest: Set true", b.getMostLimitedReasons(aapsLogger)) - b.set(aapsLogger, false, "Set false", this) + Assertions.assertEquals("ConstraintTest: Set true", b.getReasons()) + Assertions.assertEquals("ConstraintTest: Set true", b.getMostLimitedReasons()) + b.set(false, "Set false", this) 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.getMostLimitedReasons(aapsLogger)) - val d = Constraint(10.0) - d.set(aapsLogger, 5.0, "Set 5d", this) + Assertions.assertEquals("ConstraintTest: Set true\nConstraintTest: Set false", b.getReasons()) + Assertions.assertEquals("ConstraintTest: Set true\nConstraintTest: Set false", b.getMostLimitedReasons()) + val d = ConstraintObject(10.0, injector) + d.set(5.0, "Set 5d", this) Assertions.assertEquals(5.0, d.value(), 0.01) - Assertions.assertEquals("ConstraintTest: Set 5d", d.getReasons(aapsLogger)) - Assertions.assertEquals("ConstraintTest: Set 5d", d.getMostLimitedReasons(aapsLogger)) - d.setIfSmaller(aapsLogger, 6.0, "Set 6d", this) + Assertions.assertEquals("ConstraintTest: Set 5d", d.getReasons()) + Assertions.assertEquals("ConstraintTest: Set 5d", d.getMostLimitedReasons()) + d.setIfSmaller(6.0, "Set 6d", this) Assertions.assertEquals(5.0, d.value(), 0.01) - Assertions.assertEquals("ConstraintTest: Set 5d\nConstraintTest: Set 6d", d.getReasons(aapsLogger)) - Assertions.assertEquals("ConstraintTest: Set 5d", d.getMostLimitedReasons(aapsLogger)) - d.setIfSmaller(aapsLogger, 4.0, "Set 4d", this) + Assertions.assertEquals("ConstraintTest: Set 5d\nConstraintTest: Set 6d", d.getReasons()) + Assertions.assertEquals("ConstraintTest: Set 5d", d.getMostLimitedReasons()) + d.setIfSmaller(4.0, "Set 4d", this) 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 4d", d.getMostLimitedReasons(aapsLogger)) + Assertions.assertEquals("ConstraintTest: Set 5d\nConstraintTest: Set 6d\nConstraintTest: Set 4d", d.getReasons()) + Assertions.assertEquals("ConstraintTest: Set 4d", d.getMostLimitedReasons()) 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("ConstraintTest: Set 5d\nConstraintTest: Set 6d\nConstraintTest: Set 4d\nConstraintTest: Set 7d", d.getReasons(aapsLogger)) - Assertions.assertEquals("ConstraintTest: Set 4d\nConstraintTest: Set 7d", d.getMostLimitedReasons(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()) Assertions.assertEquals(10.0, d.originalValue(), 0.01) } diff --git a/core/main/src/test/java/info/nightscout/core/data/IobTotalTest.kt b/core/main/src/test/java/info/nightscout/core/data/IobTotalTest.kt index dd32259395..8067daef2a 100644 --- a/core/main/src/test/java/info/nightscout/core/data/IobTotalTest.kt +++ b/core/main/src/test/java/info/nightscout/core/data/IobTotalTest.kt @@ -9,6 +9,7 @@ import info.nightscout.core.iob.plus import info.nightscout.core.iob.round import info.nightscout.interfaces.iob.IobTotal import info.nightscout.shared.utils.DateUtil +import info.nightscout.shared.utils.DateUtilImpl import info.nightscout.sharedtests.TestBase import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.BeforeEach @@ -25,7 +26,7 @@ class IobTotalTest : TestBase() { @BeforeEach fun prepare() { - dateUtil = DateUtil(context) + dateUtil = DateUtilImpl(context) now = dateUtil.now() } diff --git a/core/main/src/test/java/info/nightscout/core/data/ProfileTest.kt b/core/main/src/test/java/info/nightscout/core/data/ProfileTest.kt index c26357af2e..100f5fac12 100644 --- a/core/main/src/test/java/info/nightscout/core/data/ProfileTest.kt +++ b/core/main/src/test/java/info/nightscout/core/data/ProfileTest.kt @@ -7,11 +7,10 @@ import info.nightscout.core.profile.ProfileSealed import info.nightscout.interfaces.Config import info.nightscout.interfaces.plugin.ActivePlugin 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.sharedPreferences.SP import info.nightscout.shared.utils.DateUtil +import info.nightscout.shared.utils.DateUtilImpl import info.nightscout.sharedtests.HardLimitsMock import info.nightscout.sharedtests.TestBase import info.nightscout.sharedtests.TestPumpPlugin @@ -37,7 +36,6 @@ class ProfileTest : TestBase() { @Mock lateinit var sp: SP private lateinit var hardLimits: HardLimits - private lateinit var rxBus: RxBus private lateinit var dateUtil: DateUtil private lateinit var testPumpPlugin: TestPumpPlugin @@ -59,8 +57,7 @@ class ProfileTest : TestBase() { @BeforeEach fun prepare() { testPumpPlugin = TestPumpPlugin { AndroidInjector { } } - dateUtil = DateUtil(context) - rxBus = RxBus(TestAapsSchedulers(), aapsLogger) + dateUtil = DateUtilImpl(context) hardLimits = HardLimitsMock(sp, rh) `when`(activePluginProvider.activePump).thenReturn(testPumpPlugin) `when`(rh.gs(info.nightscout.core.ui.R.string.profile_per_unit)).thenReturn("/U") diff --git a/core/main/src/test/java/info/nightscout/core/utils/DateUtilTest.kt b/core/main/src/test/java/info/nightscout/core/utils/DateUtilTest.kt index 472a062f98..fb3258894e 100644 --- a/core/main/src/test/java/info/nightscout/core/utils/DateUtilTest.kt +++ b/core/main/src/test/java/info/nightscout/core/utils/DateUtilTest.kt @@ -3,13 +3,13 @@ package info.nightscout.core.utils import android.content.Context import com.google.common.truth.Truth.assertThat 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.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.Assertions +import org.junit.jupiter.api.BeforeAll +import org.junit.jupiter.api.Test import org.mockito.Mock import org.mockito.Mockito.`when` import java.util.Date @@ -41,45 +41,45 @@ class DateUtilTest : TestBase() { @Test fun fromISODateStringTest() { - Assertions.assertEquals(1511124634417L, DateUtil(context).fromISODateString("2017-11-19T22:50:34.417+0200")) - Assertions.assertEquals(1511124634000L, DateUtil(context).fromISODateString("2017-11-19T22:50:34+0200")) - Assertions.assertEquals(1512317365000L, DateUtil(context).fromISODateString("2017-12-03T16:09:25.000Z")) - Assertions.assertEquals(1513902750000L, DateUtil(context).fromISODateString("2017-12-22T00:32:30Z")) + Assertions.assertEquals(1511124634417L, DateUtilImpl(context).fromISODateString("2017-11-19T22:50:34.417+0200")) + Assertions.assertEquals(1511124634000L, DateUtilImpl(context).fromISODateString("2017-11-19T22:50:34+0200")) + Assertions.assertEquals(1512317365000L, DateUtilImpl(context).fromISODateString("2017-12-03T16:09:25.000Z")) + Assertions.assertEquals(1513902750000L, DateUtilImpl(context).fromISODateString("2017-12-22T00:32:30Z")) } @Test 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() { - 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() { - Assertions.assertEquals(3600, DateUtil(context).toSeconds("01:00").toLong()) - Assertions.assertEquals(3600, DateUtil(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").toLong()) + Assertions.assertEquals(3600, DateUtilImpl(context).toSeconds("01:00 a.m.").toLong()) + Assertions.assertEquals(3600, DateUtilImpl(context).toSeconds("01:00 AM").toLong()) } @Test fun dateStringTest() { - assertThat(DateUtil(context).dateString(1513902750000L)).contains("22") + assertThat(DateUtilImpl(context).dateString(1513902750000L)).contains("22") } @Test fun timeStringTest() { - Assertions.assertTrue(DateUtil(context).timeString(1513902750000L).contains("32")) + Assertions.assertTrue(DateUtilImpl(context).timeString(1513902750000L).contains("32")) } @Test fun dateAndTimeStringTest() { - assertThat(DateUtil(context).dateAndTimeString(1513902750000L)).contains("22") - assertThat(DateUtil(context).dateAndTimeString(1513902750000L)).contains("32") + assertThat(DateUtilImpl(context).dateAndTimeString(1513902750000L)).contains("22") + assertThat(DateUtilImpl(context).dateAndTimeString(1513902750000L)).contains("32") } @Test fun dateAndTimeRangeStringTest() { - assertThat(DateUtil(context).dateAndTimeRangeString(1513902750000L, 1513902750000L)).contains("22") - assertThat(DateUtil(context).dateAndTimeRangeString(1513902750000L, 1513902750000L)).contains("32") - assertThat(DateUtil(context).dateAndTimeRangeString(1513902750000L, 1513902750000L)).contains("22") - assertThat(DateUtil(context).dateAndTimeRangeString(1513902750000L, 1513902750000L)).contains("32") + assertThat(DateUtilImpl(context).dateAndTimeRangeString(1513902750000L, 1513902750000L)).contains("22") + assertThat(DateUtilImpl(context).dateAndTimeRangeString(1513902750000L, 1513902750000L)).contains("32") + assertThat(DateUtilImpl(context).dateAndTimeRangeString(1513902750000L, 1513902750000L)).contains("22") + assertThat(DateUtilImpl(context).dateAndTimeRangeString(1513902750000L, 1513902750000L)).contains("32") } /* @@ -90,6 +90,6 @@ class DateUtilTest : TestBase() { */ @Test fun timeFrameStringTest() { `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)) } } diff --git a/core/main/test_dependencies.gradle b/core/main/test_dependencies.gradle index b4f8cf5370..04c57f1f70 100644 --- a/core/main/test_dependencies.gradle +++ b/core/main/test_dependencies.gradle @@ -12,6 +12,7 @@ dependencies { androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' androidTestImplementation "androidx.test.ext:junit-ktx:$androidx_junit_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' } diff --git a/implementation/src/main/java/info/nightscout/implementation/queue/CommandQueueImplementation.kt b/implementation/src/main/java/info/nightscout/implementation/queue/CommandQueueImplementation.kt index e66580353d..0a5fedafdd 100644 --- a/implementation/src/main/java/info/nightscout/implementation/queue/CommandQueueImplementation.kt +++ b/implementation/src/main/java/info/nightscout/implementation/queue/CommandQueueImplementation.kt @@ -9,6 +9,7 @@ import android.text.Spanned import androidx.appcompat.app.AppCompatActivity import dagger.android.HasAndroidInjector import info.nightscout.annotations.OpenForTesting +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.core.events.EventNewNotification import info.nightscout.core.extensions.getCustomizedName 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.interfaces.AndroidPermission import info.nightscout.interfaces.Config -import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.db.PersistenceLayer import info.nightscout.interfaces.notifications.Notification import info.nightscout.interfaces.plugin.ActivePlugin @@ -85,7 +85,7 @@ class CommandQueueImplementation @Inject constructor( private val rxBus: RxBus, private val aapsSchedulers: AapsSchedulers, private val rh: ResourceHelper, - private val constraintChecker: Constraints, + private val constraintChecker: ConstraintsChecker, private val profileFunction: ProfileFunction, private val activePlugin: ActivePlugin, private val context: Context, @@ -310,8 +310,8 @@ class CommandQueueImplementation @Inject constructor( removeAll(type) } // apply constraints - detailedBolusInfo.insulin = constraintChecker.applyBolusConstraints(Constraint(detailedBolusInfo.insulin)).value() - detailedBolusInfo.carbs = constraintChecker.applyCarbsConstraints(Constraint(detailedBolusInfo.carbs.toInt())).value().toDouble() + detailedBolusInfo.insulin = constraintChecker.applyBolusConstraints(ConstraintObject(detailedBolusInfo.insulin, injector)).value() + detailedBolusInfo.carbs = constraintChecker.applyCarbsConstraints(ConstraintObject(detailedBolusInfo.carbs.toInt(), injector)).value().toDouble() // add new command to queue if (detailedBolusInfo.bolusType == DetailedBolusInfo.BolusType.SMB) { add(CommandSMBBolus(injector, detailedBolusInfo, callback)) @@ -368,7 +368,7 @@ class CommandQueueImplementation @Inject constructor( } // remove all unfinished 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(CommandTempBasalAbsolute(injector, rateAfterConstraints, durationInMinutes, enforceNew, profile, tbrType, callback)) notifyAboutNewCommand() @@ -383,7 +383,7 @@ class CommandQueueImplementation @Inject constructor( } // remove all unfinished 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(CommandTempBasalPercent(injector, percentAfterConstraints, durationInMinutes, enforceNew, profile, tbrType, callback)) notifyAboutNewCommand() @@ -396,7 +396,7 @@ class CommandQueueImplementation @Inject constructor( callback?.result(executingNowError())?.run() return false } - val rateAfterConstraints = constraintChecker.applyExtendedBolusConstraints(Constraint(insulin)).value() + val rateAfterConstraints = constraintChecker.applyExtendedBolusConstraints(ConstraintObject(insulin, injector)).value() // remove all unfinished removeAll(CommandType.EXTENDEDBOLUS) // add new command to queue diff --git a/implementation/src/test/java/info/nightscout/implementation/queue/CommandQueueImplementationTest.kt b/implementation/src/test/java/info/nightscout/implementation/queue/CommandQueueImplementationTest.kt index f77ea1b704..d331d044ce 100644 --- a/implementation/src/test/java/info/nightscout/implementation/queue/CommandQueueImplementationTest.kt +++ b/implementation/src/test/java/info/nightscout/implementation/queue/CommandQueueImplementationTest.kt @@ -5,6 +5,7 @@ import android.os.Handler import android.os.PowerManager import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.core.utils.fabric.FabricPrivacy import info.nightscout.database.ValueWrapper 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.interfaces.AndroidPermission import info.nightscout.interfaces.Config -import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.db.PersistenceLayer import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.profile.ProfileFunction @@ -50,7 +50,7 @@ import java.util.Calendar class CommandQueueImplementationTest : TestBaseWithProfile() { - @Mock lateinit var constraintChecker: Constraints + @Mock lateinit var constraintChecker: ConstraintsChecker @Mock lateinit var powerManager: PowerManager @Mock lateinit var repository: AppRepository @Mock lateinit var uiInteraction: UiInteraction @@ -63,7 +63,7 @@ class CommandQueueImplementationTest : TestBaseWithProfile() { rxBus: RxBus, aapsSchedulers: AapsSchedulers, rh: ResourceHelper, - constraintChecker: Constraints, + constraintChecker: ConstraintsChecker, profileFunction: ProfileFunction, activePlugin: ActivePlugin, context: Context, @@ -88,6 +88,9 @@ class CommandQueueImplementationTest : TestBaseWithProfile() { private val injector = HasAndroidInjector { AndroidInjector { + if (it is ConstraintObject<*>) { + it.aapsLogger = aapsLogger + } if (it is Command) { it.aapsLogger = aapsLogger it.rh = rh @@ -140,14 +143,14 @@ class CommandQueueImplementationTest : TestBaseWithProfile() { ) `when`(profileFunction.getProfile()).thenReturn(validProfile) - val bolusConstraint = Constraint(0.0) + val bolusConstraint = ConstraintObject(0.0, injector) `when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(bolusConstraint) `when`(constraintChecker.applyExtendedBolusConstraints(anyObject())).thenReturn(bolusConstraint) - val carbsConstraint = Constraint(0) + val carbsConstraint = ConstraintObject(0, injector) `when`(constraintChecker.applyCarbsConstraints(anyObject())).thenReturn(carbsConstraint) - val rateConstraint = Constraint(0.0) + val rateConstraint = ConstraintObject(0.0, injector) `when`(constraintChecker.applyBasalConstraints(anyObject(), anyObject())).thenReturn(rateConstraint) - val percentageConstraint = Constraint(0) + val percentageConstraint = ConstraintObject(0, injector) `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.format_insulin_units)).thenReturn("%1\$.2f U") diff --git a/implementation/src/test/java/info/nightscout/implementation/queue/QueueThreadTest.kt b/implementation/src/test/java/info/nightscout/implementation/queue/QueueThreadTest.kt index f8e3494ac5..efbfd84f95 100644 --- a/implementation/src/test/java/info/nightscout/implementation/queue/QueueThreadTest.kt +++ b/implementation/src/test/java/info/nightscout/implementation/queue/QueueThreadTest.kt @@ -4,11 +4,11 @@ import android.content.Context import android.os.PowerManager import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.database.impl.AppRepository import info.nightscout.implementation.queue.commands.CommandTempBasalAbsolute import info.nightscout.interfaces.AndroidPermission -import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.db.PersistenceLayer import info.nightscout.interfaces.pump.PumpSync import info.nightscout.interfaces.pump.defs.PumpDescription @@ -25,7 +25,7 @@ import org.mockito.Mockito class QueueThreadTest : TestBaseWithProfile() { - @Mock lateinit var constraintChecker: Constraints + @Mock lateinit var constraintChecker: ConstraintsChecker @Mock lateinit var powerManager: PowerManager @Mock lateinit var repository: AppRepository @Mock lateinit var androidPermission: AndroidPermission @@ -34,6 +34,9 @@ class QueueThreadTest : TestBaseWithProfile() { private val injector = HasAndroidInjector { AndroidInjector { + if (it is ConstraintObject<*>) { + it.aapsLogger = aapsLogger + } if (it is Command) { it.aapsLogger = aapsLogger it.rh = rh @@ -64,14 +67,14 @@ class QueueThreadTest : TestBaseWithProfile() { Mockito.`when`(context.getSystemService(Context.POWER_SERVICE)).thenReturn(powerManager) 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.applyExtendedBolusConstraints(anyObject())).thenReturn(bolusConstraint) - val carbsConstraint = Constraint(0) + val carbsConstraint = ConstraintObject(0, injector) 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) - val percentageConstraint = Constraint(0) + val percentageConstraint = ConstraintObject(0, injector) Mockito.`when`(constraintChecker.applyBasalPercentConstraints(anyObject(), anyObject())) .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") diff --git a/implementation/src/test/java/info/nightscout/implementation/wizard/BolusWizardTest.kt b/implementation/src/test/java/info/nightscout/implementation/wizard/BolusWizardTest.kt index 707134a5ab..1435c70843 100644 --- a/implementation/src/test/java/info/nightscout/implementation/wizard/BolusWizardTest.kt +++ b/implementation/src/test/java/info/nightscout/implementation/wizard/BolusWizardTest.kt @@ -8,12 +8,11 @@ import info.nightscout.implementation.iob.GlucoseStatusProviderImpl import info.nightscout.interfaces.aps.AutosensDataStore import info.nightscout.interfaces.aps.Loop 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.profile.Profile import info.nightscout.interfaces.pump.defs.PumpDescription import info.nightscout.interfaces.queue.CommandQueue -import info.nightscout.rx.bus.RxBus import info.nightscout.sharedtests.TestBaseWithProfile import org.junit.jupiter.api.Test import org.mockito.Mock @@ -24,7 +23,7 @@ class BolusWizardTest : TestBaseWithProfile() { private val pumpBolusStep = 0.1 - @Mock lateinit var constraintChecker: Constraints + @Mock lateinit var constraintChecker: ConstraintsChecker @Mock lateinit var commandQueue: CommandQueue @Mock lateinit var loop: Loop @Mock lateinit var autosensDataStore: AutosensDataStore @@ -34,7 +33,7 @@ class BolusWizardTest : TestBaseWithProfile() { if (it is BolusWizard) { it.aapsLogger = aapsLogger it.rh = rh - it.rxBus = RxBus(aapsSchedulers, aapsLogger) + it.rxBus = rxBus it.profileFunction = profileFunction it.constraintChecker = constraintChecker it.activePlugin = activePlugin @@ -113,7 +112,7 @@ class BolusWizardTest : TestBaseWithProfile() { useAlarm = false ) val bolusForBg54 = bw.calculatedTotalInsulin - assertThat(bolusForBg54).isWithin( 0.01).of(bolusForBg42) + assertThat(bolusForBg54).isWithin(0.01).of(bolusForBg42) } @Test diff --git a/insight/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java b/insight/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java index 60f7e05443..34c5314473 100644 --- a/insight/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java +++ b/insight/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java @@ -103,7 +103,7 @@ import info.nightscout.androidaps.plugins.pump.insight.utils.ParameterBlockUtil; import info.nightscout.core.events.EventNewNotification; import info.nightscout.interfaces.Config; 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.plugin.OwnDatabasePlugin; import info.nightscout.interfaces.plugin.PluginDescription; @@ -134,9 +134,10 @@ import info.nightscout.shared.utils.DateUtil; import info.nightscout.shared.utils.T; @Singleton -public class LocalInsightPlugin extends PumpPluginBase implements Pump, Insight, Constraints, OwnDatabasePlugin, +public class LocalInsightPlugin extends PumpPluginBase implements Pump, Insight, PluginConstraints, OwnDatabasePlugin, InsightConnectionService.StateCallback { + public static final String ALERT_CHANNEL_ID = "AAPS-InsightAlert"; private final AAPSLogger aapsLogger; private final RxBus rxBus; private final ResourceHelper rh; @@ -148,13 +149,12 @@ public class LocalInsightPlugin extends PumpPluginBase implements Pump, Insight, private final InsightDbHelper insightDbHelper; private final PumpSync pumpSync; private final InsightDatabase insightDatabase; - - public static final String ALERT_CHANNEL_ID = "AAPS-InsightAlert"; - private final PumpDescription pumpDescription; + private final Object $bolusLock = new Object[0]; + public double lastBolusAmount = 0; + public long lastBolusTimestamp = 0L; private InsightAlertService alertService; private InsightConnectionService connectionService; - private long timeOffset; private final ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder binder) { @@ -174,8 +174,7 @@ public class LocalInsightPlugin extends PumpPluginBase implements Pump, Insight, connectionService = null; } }; - - private final Object $bolusLock = new Object[0]; + private long timeOffset; private int bolusID; private boolean bolusCancelled; private BasalProfile activeBasalProfile; @@ -192,8 +191,6 @@ public class LocalInsightPlugin extends PumpPluginBase implements Pump, Insight, private List activeBoluses; private boolean statusLoaded; private TBROverNotificationBlock tbrOverNotificationBlock; - public double lastBolusAmount = 0; - public long lastBolusTimestamp = 0L; @Inject public LocalInsightPlugin( @@ -1589,22 +1586,22 @@ public class LocalInsightPlugin extends PumpPluginBase implements Pump, Insight, @NonNull @Override public Constraint applyBasalPercentConstraints(Constraint 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.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.setIfGreater(0, rh.gs(info.nightscout.core.ui.R.string.limitingpercentrate, 0, rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), 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; } @NonNull @Override public Constraint applyBolusConstraints(@NonNull Constraint 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) { //TODO: Add function to Constraints or use different approach // 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 - 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; } diff --git a/plugins/aps/src/main/java/info/nightscout/plugins/aps/APSResultObject.kt b/plugins/aps/src/main/java/info/nightscout/plugins/aps/APSResultObject.kt index c630615858..3ad966c702 100644 --- a/plugins/aps/src/main/java/info/nightscout/plugins/aps/APSResultObject.kt +++ b/plugins/aps/src/main/java/info/nightscout/plugins/aps/APSResultObject.kt @@ -9,7 +9,7 @@ import info.nightscout.core.utils.HtmlHelper import info.nightscout.database.entities.GlucoseValue import info.nightscout.interfaces.aps.APSResult 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.IobTotal import info.nightscout.interfaces.plugin.ActivePlugin @@ -34,7 +34,7 @@ import kotlin.math.max open class APSResultObject @Inject constructor(val injector: HasAndroidInjector) : APSResult { @Inject lateinit var aapsLogger: AAPSLogger - @Inject lateinit var constraintChecker: Constraints + @Inject lateinit var constraintChecker: ConstraintsChecker @Inject lateinit var sp: SP @Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var iobCobCalculator: IobCobCalculator @@ -74,12 +74,12 @@ open class APSResultObject @Inject constructor(val injector: HasAndroidInjector) val pump = activePlugin.activePump if (isChangeRequested) { // rate - var ret: String = if (rate == 0.0 && duration == 0) "${rh.gs(info.nightscout.core.ui.R.string.cancel_temp)} " - else if (rate == -1.0) "${rh.gs(info.nightscout.core.ui.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) " + - "${rh.gs(info.nightscout.core.ui.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)}%) " + - "${rh.gs(info.nightscout.core.ui.R.string.duration)}: ${decimalFormatter.to2Decimal(duration.toDouble())} min " + var ret: String = if (rate == 0.0 && duration == 0) "${rh.gs(R.string.cancel_temp)} " + else if (rate == -1.0) "${rh.gs(R.string.let_temp_basal_run)}\n" + else if (usePercent) "${rh.gs(R.string.rate)}: ${decimalFormatter.to2Decimal(percent.toDouble())}% (${decimalFormatter.to2Decimal(percent * pump.baseBasalRate / 100.0)} U/h) " + + "${rh.gs(R.string.duration)}: ${decimalFormatter.to2Decimal(duration.toDouble())} min " + else "${rh.gs(R.string.rate)}: ${decimalFormatter.to2Decimal(rate)} U/h (${decimalFormatter.to2Decimal(rate / pump.baseBasalRate * 100)}%) " + + "${rh.gs(R.string.duration)}: ${decimalFormatter.to2Decimal(duration.toDouble())} min " // smb if (smb != 0.0) ret += "SMB: ${decimalFormatter.toPumpSupportedBolus(smb, activePlugin.activePump.pumpDescription.bolusStep)} " if (isCarbsRequired) { @@ -92,7 +92,7 @@ open class APSResultObject @Inject constructor(val injector: HasAndroidInjector) } return if (isCarbsRequired) { carbsRequiredText - } else rh.gs(info.nightscout.core.ui.R.string.nochangerequested) + } else rh.gs(R.string.nochangerequested) } override fun toSpanned(): Spanned { @@ -100,17 +100,17 @@ open class APSResultObject @Inject constructor(val injector: HasAndroidInjector) if (isChangeRequested) { // rate var ret: String = - if (rate == 0.0 && duration == 0) rh.gs(info.nightscout.core.ui.R.string.cancel_temp) + "
" else if (rate == -1.0) rh.gs(info.nightscout.core.ui.R.string.let_temp_basal_run) + "
" else if (usePercent) "" + rh.gs( - info.nightscout.core.ui.R.string.rate + if (rate == 0.0 && duration == 0) rh.gs(R.string.cancel_temp) + "
" else if (rate == -1.0) rh.gs(R.string.let_temp_basal_run) + "
" 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
" else "" + rh.gs(info.nightscout.core.ui.R.string.rate) + ": " + decimalFormatter.to2Decimal( + "" + rh.gs(R.string.duration) + ": " + decimalFormatter.to2Decimal(duration.toDouble()) + " min
" else "" + rh.gs(R.string.rate) + ": " + decimalFormatter.to2Decimal( rate ) + " U/h " + "(" + decimalFormatter.to2Decimal(rate / pump.baseBasalRate * 100.0) + "%)
" + - "" + 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 if (smb != 0.0) ret += "" + "SMB" + ": " + decimalFormatter.toPumpSupportedBolus(smb, activePlugin.activePump.pumpDescription.bolusStep) + "
" diff --git a/plugins/aps/src/main/java/info/nightscout/plugins/aps/OpenAPSFragment.kt b/plugins/aps/src/main/java/info/nightscout/plugins/aps/OpenAPSFragment.kt index 568819f482..81c6df8f15 100644 --- a/plugins/aps/src/main/java/info/nightscout/plugins/aps/OpenAPSFragment.kt +++ b/plugins/aps/src/main/java/info/nightscout/plugins/aps/OpenAPSFragment.kt @@ -150,7 +150,7 @@ class OpenAPSFragment : DaggerFragment(), MenuProvider { binding.mealdata.text = jsonFormatter.format(determineBasalAdapter.mealDataParam) binding.scriptdebugdata.text = determineBasalAdapter.scriptDebug.replace("\\s+".toRegex(), " ") openAPSPlugin.lastAPSResult?.inputConstraints?.let { - binding.constraints.text = it.getReasons(aapsLogger) + binding.constraints.text = it.getReasons() } } if (openAPSPlugin.lastAPSRun != 0L) { diff --git a/plugins/aps/src/main/java/info/nightscout/plugins/aps/loop/LoopFragment.kt b/plugins/aps/src/main/java/info/nightscout/plugins/aps/loop/LoopFragment.kt index 031f100c20..1cd172046e 100644 --- a/plugins/aps/src/main/java/info/nightscout/plugins/aps/loop/LoopFragment.kt +++ b/plugins/aps/src/main/java/info/nightscout/plugins/aps/loop/LoopFragment.kt @@ -12,12 +12,13 @@ import android.view.ViewGroup import androidx.core.view.MenuCompat import androidx.core.view.MenuProvider import androidx.lifecycle.Lifecycle +import dagger.android.HasAndroidInjector import dagger.android.support.DaggerFragment +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.core.pump.toHtml import info.nightscout.core.utils.HtmlHelper import info.nightscout.core.utils.fabric.FabricPrivacy import info.nightscout.interfaces.aps.Loop -import info.nightscout.interfaces.constraints.Constraint import info.nightscout.interfaces.utils.DecimalFormatter import info.nightscout.plugins.aps.R import info.nightscout.plugins.aps.databinding.LoopFragmentBinding @@ -44,6 +45,7 @@ class LoopFragment : DaggerFragment(), MenuProvider { @Inject lateinit var loop: Loop @Inject lateinit var dateUtil: DateUtil @Inject lateinit var decimalFormatter: DecimalFormatter + @Inject lateinit var injector: HasAndroidInjector @Suppress("PrivatePropertyName") private val ID_MENU_RUN = 501 @@ -150,12 +152,12 @@ class LoopFragment : DaggerFragment(), MenuProvider { var constraints = it.constraintsProcessed?.let { constraintsProcessed -> - val allConstraints = Constraint(0.0) + val allConstraints = ConstraintObject(0.0, injector) constraintsProcessed.rateConstraint?.let { rateConstraint -> allConstraints.copyReasons(rateConstraint) } 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.swipeRefresh.isRefreshing = false } diff --git a/plugins/aps/src/main/java/info/nightscout/plugins/aps/loop/LoopPlugin.kt b/plugins/aps/src/main/java/info/nightscout/plugins/aps/loop/LoopPlugin.kt index 660b9b92e1..787938d90a 100644 --- a/plugins/aps/src/main/java/info/nightscout/plugins/aps/loop/LoopPlugin.kt +++ b/plugins/aps/src/main/java/info/nightscout/plugins/aps/loop/LoopPlugin.kt @@ -14,6 +14,7 @@ import android.os.SystemClock import androidx.core.app.NotificationCompat import dagger.android.HasAndroidInjector import info.nightscout.annotations.OpenForTesting +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.core.events.EventNewNotification import info.nightscout.core.extensions.convertedToAbsolute 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.LastRun 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.logging.UserEntryLogger import info.nightscout.interfaces.notifications.Notification @@ -91,7 +92,7 @@ class LoopPlugin @Inject constructor( private val rxBus: RxBus, private val sp: SP, private val config: Config, - private val constraintChecker: Constraints, + private val constraintChecker: ConstraintsChecker, rh: ResourceHelper, private val profileFunction: ProfileFunction, private val context: Context, @@ -230,7 +231,7 @@ class LoopPlugin @Inject constructor( if (!loopEnabled.value()) { val message = """ ${rh.gs(info.nightscout.core.ui.R.string.loop_disabled)} - ${loopEnabled.getReasons(aapsLogger)} + ${loopEnabled.getReasons()} """.trimIndent() aapsLogger.debug(LTag.APS, message) rxBus.send(EventLoopSetLastRunGui(message)) @@ -274,11 +275,11 @@ class LoopPlugin @Inject constructor( // check rate for constraints 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.percentConstraint = Constraint(resultAfterConstraints.percent) + resultAfterConstraints.percentConstraint = ConstraintObject(resultAfterConstraints.percent, injector) 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() // safety check for multiple SMBs diff --git a/plugins/aps/src/main/java/info/nightscout/plugins/aps/openAPSAMA/DetermineBasalAdapterAMAJS.kt b/plugins/aps/src/main/java/info/nightscout/plugins/aps/openAPSAMA/DetermineBasalAdapterAMAJS.kt index 99f56f187d..4ae6517b9c 100644 --- a/plugins/aps/src/main/java/info/nightscout/plugins/aps/openAPSAMA/DetermineBasalAdapterAMAJS.kt +++ b/plugins/aps/src/main/java/info/nightscout/plugins/aps/openAPSAMA/DetermineBasalAdapterAMAJS.kt @@ -7,7 +7,7 @@ import info.nightscout.core.extensions.plannedRemainingMinutes import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.aps.DetermineBasalAdapter 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.IobCobCalculator import info.nightscout.interfaces.iob.IobTotal @@ -43,7 +43,7 @@ class DetermineBasalAdapterAMAJS internal constructor(scriptReader: ScriptReader private val injector: HasAndroidInjector @Inject lateinit var aapsLogger: AAPSLogger - @Inject lateinit var constraintChecker: Constraints + @Inject lateinit var constraintChecker: ConstraintsChecker @Inject lateinit var sp: SP @Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var iobCobCalculator: IobCobCalculator @@ -107,7 +107,8 @@ class DetermineBasalAdapterAMAJS internal constructor(scriptReader: ScriptReader makeParam(profile, rhino, scope), makeParam(autosensData, rhino, scope), makeParam(mealData, rhino, scope), - setTempBasalFunctionsObj) + setTempBasalFunctionsObj + ) val jsResult = determineBasalObj.call(rhino, scope, scope, params) as NativeObject scriptDebug = LoggerCallback.scriptDebug diff --git a/plugins/aps/src/main/java/info/nightscout/plugins/aps/openAPSAMA/OpenAPSAMAPlugin.kt b/plugins/aps/src/main/java/info/nightscout/plugins/aps/openAPSAMA/OpenAPSAMAPlugin.kt index 61af8fa1b6..ae7e8192c3 100644 --- a/plugins/aps/src/main/java/info/nightscout/plugins/aps/openAPSAMA/OpenAPSAMAPlugin.kt +++ b/plugins/aps/src/main/java/info/nightscout/plugins/aps/openAPSAMA/OpenAPSAMAPlugin.kt @@ -3,6 +3,7 @@ package info.nightscout.plugins.aps.openAPSAMA import android.content.Context import dagger.android.HasAndroidInjector import info.nightscout.annotations.OpenForTesting +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.core.extensions.target import info.nightscout.core.utils.MidnightUtils 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.DetermineBasalAdapter 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.IobCobCalculator import info.nightscout.interfaces.plugin.ActivePlugin @@ -46,7 +48,7 @@ class OpenAPSAMAPlugin @Inject constructor( injector: HasAndroidInjector, aapsLogger: AAPSLogger, private val rxBus: RxBus, - private val constraintChecker: Constraints, + private val constraintChecker: ConstraintsChecker, rh: ResourceHelper, private val profileFunction: ProfileFunction, private val context: Context, @@ -69,7 +71,7 @@ class OpenAPSAMAPlugin @Inject constructor( .preferencesId(R.xml.pref_openapsama) .description(R.string.description_ama), aapsLogger, rh, injector -), APS, Constraints { +), APS, PluginConstraints { // last values 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)) 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 { inputConstraints.copyReasons(it) }.value() @@ -237,8 +239,8 @@ class OpenAPSAMAPlugin @Inject constructor( override fun applyMaxIOBConstraints(maxIob: Constraint): Constraint { if (isEnabled()) { 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(aapsLogger, hardLimits.maxIobAMA(), rh.gs(R.string.limiting_iob, hardLimits.maxIobAMA(), rh.gs(R.string.hardlimit)), this) + maxIob.setIfSmaller(maxIobPref, rh.gs(R.string.limiting_iob, maxIobPref, rh.gs(R.string.maxvalueinpreferences)), this) + maxIob.setIfSmaller(hardLimits.maxIobAMA(), rh.gs(R.string.limiting_iob, hardLimits.maxIobAMA(), rh.gs(R.string.hardlimit)), this) } return maxIob } @@ -250,27 +252,26 @@ class OpenAPSAMAPlugin @Inject constructor( maxBasal = profile.getMaxDailyBasal() 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 val maxBasalMultiplier = sp.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4.0) val maxFromBasalMultiplier = floor(maxBasalMultiplier * profile.getBasal() * 100) / 100 absoluteRate.setIfSmaller( - aapsLogger, maxFromBasalMultiplier, rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, maxFromBasalMultiplier, rh.gs(R.string.max_basal_multiplier)), this ) val maxBasalFromDaily = sp.getDouble(R.string.key_openapsama_max_daily_safety_multiplier, 3.0) 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 } override fun isAutosensModeEnabled(value: Constraint): Constraint { 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 } } \ No newline at end of file diff --git a/plugins/aps/src/main/java/info/nightscout/plugins/aps/openAPSSMB/DetermineBasalAdapterSMBJS.kt b/plugins/aps/src/main/java/info/nightscout/plugins/aps/openAPSSMB/DetermineBasalAdapterSMBJS.kt index 89c7e6f9ba..bc15d9ccde 100644 --- a/plugins/aps/src/main/java/info/nightscout/plugins/aps/openAPSSMB/DetermineBasalAdapterSMBJS.kt +++ b/plugins/aps/src/main/java/info/nightscout/plugins/aps/openAPSSMB/DetermineBasalAdapterSMBJS.kt @@ -7,7 +7,7 @@ import info.nightscout.core.extensions.plannedRemainingMinutes import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.aps.DetermineBasalAdapter 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.IobCobCalculator 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 { @Inject lateinit var aapsLogger: AAPSLogger - @Inject lateinit var constraintChecker: Constraints + @Inject lateinit var constraintChecker: ConstraintsChecker @Inject lateinit var sp: SP @Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var iobCobCalculator: IobCobCalculator diff --git a/plugins/aps/src/main/java/info/nightscout/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.kt b/plugins/aps/src/main/java/info/nightscout/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.kt index 5d528e4b5d..8c93012f07 100644 --- a/plugins/aps/src/main/java/info/nightscout/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.kt +++ b/plugins/aps/src/main/java/info/nightscout/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.kt @@ -4,6 +4,7 @@ import android.content.Context import androidx.preference.PreferenceFragmentCompat import androidx.preference.SwitchPreference import dagger.android.HasAndroidInjector +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.core.extensions.target import info.nightscout.core.utils.MidnightUtils 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.bgQualityCheck.BgQualityCheck 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.IobCobCalculator import info.nightscout.interfaces.plugin.ActivePlugin @@ -44,7 +46,7 @@ open class OpenAPSSMBPlugin @Inject constructor( injector: HasAndroidInjector, aapsLogger: AAPSLogger, private val rxBus: RxBus, - private val constraintChecker: Constraints, + private val constraintChecker: ConstraintsChecker, rh: ResourceHelper, private val profileFunction: ProfileFunction, val context: Context, @@ -69,7 +71,7 @@ open class OpenAPSSMBPlugin @Inject constructor( .description(R.string.description_smb) .setDefault(), aapsLogger, rh, injector -), APS, Constraints { +), APS, PluginConstraints { // DynamicISF specific var tdd1D: Double? = null @@ -77,7 +79,7 @@ open class OpenAPSSMBPlugin @Inject constructor( var tddLast24H: Double? = null var tddLast4H: Double? = null var tddLast8to4H: Double? = null - var dynIsfEnabled: Constraint = Constraint(false) + var dynIsfEnabled: Constraint = ConstraintObject(false, injector) // last values override var lastAPSRun: Long = 0 @@ -129,7 +131,7 @@ open class OpenAPSSMBPlugin @Inject constructor( 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 { inputConstraints.copyReasons(it) }.value() @@ -207,19 +209,19 @@ open class OpenAPSSMBPlugin @Inject constructor( val iobArray = iobCobCalculator.calculateIobArrayForSMB(lastAutosensResult, SMBDefaults.exercise_mode, SMBDefaults.half_basal_exercise_target, isTempTarget) profiler.log(LTag.APS, "calculateIobArrayInDia()", startPart) startPart = System.currentTimeMillis() - val smbAllowed = Constraint(!tempBasalFallback).also { + val smbAllowed = ConstraintObject(!tempBasalFallback, injector).also { constraintChecker.isSMBModeEnabled(it) inputConstraints.copyReasons(it) } - val advancedFiltering = Constraint(!tempBasalFallback).also { + val advancedFiltering = ConstraintObject(!tempBasalFallback, injector).also { constraintChecker.isAdvancedFilteringEnabled(it) inputConstraints.copyReasons(it) } - val uam = Constraint(true).also { + val uam = ConstraintObject(true, injector).also { constraintChecker.isUAMEnabled(it) inputConstraints.copyReasons(it) } - dynIsfEnabled = Constraint(true).also { + dynIsfEnabled = ConstraintObject(true, injector).also { constraintChecker.isDynIsfModeEnabled(it) inputConstraints.copyReasons(it) } @@ -239,12 +241,12 @@ open class OpenAPSSMBPlugin @Inject constructor( if (tdd1D == null || tdd7D == null || tddLast4H == null || tddLast8to4H == null || tddLast24H == null) { inputConstraints.copyReasons( - Constraint(false).also { - it.set(aapsLogger, false, rh.gs(R.string.fallback_smb_no_tdd), this) + ConstraintObject(false, injector).also { + it.set(false, rh.gs(R.string.fallback_smb_no_tdd), this) } ) 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): Constraint { - value.set(aapsLogger, false) + value.set(false) return value } override fun applyMaxIOBConstraints(maxIob: Constraint): Constraint { if (isEnabled()) { 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(aapsLogger, hardLimits.maxIobSMB(), rh.gs(R.string.limiting_iob, hardLimits.maxIobSMB(), rh.gs(R.string.hardlimit)), this) + maxIob.setIfSmaller(maxIobPref, rh.gs(R.string.limiting_iob, maxIobPref, rh.gs(R.string.maxvalueinpreferences)), this) + maxIob.setIfSmaller(hardLimits.maxIobSMB(), rh.gs(R.string.limiting_iob, hardLimits.maxIobSMB(), rh.gs(R.string.hardlimit)), this) } return maxIob } @@ -313,39 +315,38 @@ open class OpenAPSSMBPlugin @Inject constructor( maxBasal = profile.getMaxDailyBasal() 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 val maxBasalMultiplier = sp.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4.0) val maxFromBasalMultiplier = floor(maxBasalMultiplier * profile.getBasal() * 100) / 100 absoluteRate.setIfSmaller( - aapsLogger, maxFromBasalMultiplier, rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, maxFromBasalMultiplier, rh.gs(R.string.max_basal_multiplier)), this ) val maxBasalFromDaily = sp.getDouble(R.string.key_openapsama_max_daily_safety_multiplier, 3.0) 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 } override fun isSMBModeEnabled(value: Constraint): Constraint { 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 } override fun isUAMEnabled(value: Constraint): Constraint { 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 } override fun isAutosensModeEnabled(value: Constraint): Constraint { 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 } diff --git a/plugins/aps/src/main/java/info/nightscout/plugins/aps/openAPSSMBDynamicISF/OpenAPSSMBDynamicISFPlugin.kt b/plugins/aps/src/main/java/info/nightscout/plugins/aps/openAPSSMBDynamicISF/OpenAPSSMBDynamicISFPlugin.kt index 2b83d11856..9ade4e2cde 100644 --- a/plugins/aps/src/main/java/info/nightscout/plugins/aps/openAPSSMBDynamicISF/OpenAPSSMBDynamicISFPlugin.kt +++ b/plugins/aps/src/main/java/info/nightscout/plugins/aps/openAPSSMBDynamicISF/OpenAPSSMBDynamicISFPlugin.kt @@ -6,7 +6,7 @@ import info.nightscout.annotations.OpenForTesting import info.nightscout.database.impl.AppRepository import info.nightscout.interfaces.aps.DetermineBasalAdapter 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.IobCobCalculator import info.nightscout.interfaces.plugin.ActivePlugin @@ -32,7 +32,7 @@ class OpenAPSSMBDynamicISFPlugin @Inject constructor( injector: HasAndroidInjector, aapsLogger: AAPSLogger, rxBus: RxBus, - constraintChecker: Constraints, + constraintChecker: ConstraintsChecker, rh: ResourceHelper, profileFunction: ProfileFunction, context: Context, diff --git a/plugins/aps/src/test/java/info/nightscout/plugins/aps/loop/APSResultTest.kt b/plugins/aps/src/test/java/info/nightscout/plugins/aps/loop/APSResultTest.kt index 422da5253c..3f926606f6 100644 --- a/plugins/aps/src/test/java/info/nightscout/plugins/aps/loop/APSResultTest.kt +++ b/plugins/aps/src/test/java/info/nightscout/plugins/aps/loop/APSResultTest.kt @@ -2,11 +2,11 @@ package info.nightscout.plugins.aps.loop import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.core.utils.JsonHelper.safeGetDouble import info.nightscout.database.entities.TemporaryBasal import info.nightscout.interfaces.aps.APSResult -import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.pump.defs.PumpType import info.nightscout.sharedtests.TestBaseWithProfile import org.junit.jupiter.api.Assertions @@ -18,11 +18,11 @@ import org.mockito.Mockito.`when` class APSResultTest : TestBaseWithProfile() { - @Mock lateinit var constraints: Constraints + @Mock lateinit var constraintsChecker: ConstraintsChecker private val injector = HasAndroidInjector { AndroidInjector { } } - private var closedLoopEnabled = Constraint(false) + private var closedLoopEnabled = ConstraintObject(false, injector) private fun APSResult.percent(percent: Int): APSResult { this.percent = percent @@ -55,7 +55,7 @@ class APSResultTest : TestBaseWithProfile() { val apsResult = info.nightscout.plugins.aps.APSResultObject { AndroidInjector { } } .also { it.aapsLogger = aapsLogger - it.constraintChecker = constraints + it.constraintChecker = constraintsChecker it.sp = sp it.activePlugin = activePlugin it.iobCobCalculator = iobCobCalculator @@ -70,7 +70,7 @@ class APSResultTest : TestBaseWithProfile() { apsResult.usePercent(true) // closed loop mode return original request - closedLoopEnabled.set(aapsLogger, true) + closedLoopEnabled.set(true) `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(null) apsResult.tempBasalRequested(false) Assertions.assertEquals(false, apsResult.isChangeRequested) @@ -78,7 +78,7 @@ class APSResultTest : TestBaseWithProfile() { Assertions.assertEquals(true, apsResult.isChangeRequested) // open loop - closedLoopEnabled.set(aapsLogger, false) + closedLoopEnabled.set(false) // no change requested `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(null) apsResult.tempBasalRequested(false) @@ -184,7 +184,7 @@ class APSResultTest : TestBaseWithProfile() { apsResult.usePercent(false) // open loop - closedLoopEnabled.set(aapsLogger, false) + closedLoopEnabled.set(false) // request 100% when no temp is running `when`(iobCobCalculator.getTempBasalIncludingConvertedExtended(ArgumentMatchers.anyLong())).thenReturn(null) apsResult.tempBasalRequested(true).rate(1.0).duration(30) @@ -296,7 +296,7 @@ class APSResultTest : TestBaseWithProfile() { val apsResult = info.nightscout.plugins.aps.APSResultObject { AndroidInjector { } } .also { it.aapsLogger = aapsLogger - it.constraintChecker = constraints + it.constraintChecker = constraintsChecker it.sp = sp it.activePlugin = activePlugin it.iobCobCalculator = iobCobCalculator @@ -309,11 +309,11 @@ class APSResultTest : TestBaseWithProfile() { } @Test fun jsonTest() { - closedLoopEnabled.set(aapsLogger, true) + closedLoopEnabled.set(true) val apsResult = info.nightscout.plugins.aps.APSResultObject { AndroidInjector { } } .also { it.aapsLogger = aapsLogger - it.constraintChecker = constraints + it.constraintChecker = constraintsChecker it.sp = sp it.activePlugin = activePlugin it.iobCobCalculator = iobCobCalculator @@ -328,7 +328,7 @@ class APSResultTest : TestBaseWithProfile() { @BeforeEach 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`(profileFunction.getProfile()).thenReturn(validProfile) } diff --git a/plugins/automation/build.gradle b/plugins/automation/build.gradle index 2fecd1f02e..94a09517e0 100644 --- a/plugins/automation/build.gradle +++ b/plugins/automation/build.gradle @@ -26,6 +26,7 @@ dependencies { implementation project(':database:impl') testImplementation project(':app-wear-shared:shared-tests') + testImplementation project(':app-wear-shared:shared-impl') testImplementation project(':implementation') testImplementation project(':plugins:main') diff --git a/plugins/automation/src/main/java/info/nightscout/automation/AutomationPlugin.kt b/plugins/automation/src/main/java/info/nightscout/automation/AutomationPlugin.kt index 725788bebb..7d2c20da06 100644 --- a/plugins/automation/src/main/java/info/nightscout/automation/AutomationPlugin.kt +++ b/plugins/automation/src/main/java/info/nightscout/automation/AutomationPlugin.kt @@ -49,7 +49,7 @@ import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.aps.Loop import info.nightscout.interfaces.automation.Automation 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.PluginBase import info.nightscout.interfaces.plugin.PluginDescription @@ -87,7 +87,7 @@ class AutomationPlugin @Inject constructor( private val fabricPrivacy: FabricPrivacy, private val loop: Loop, private val rxBus: RxBus, - private val constraintChecker: Constraints, + private val constraintChecker: ConstraintsChecker, aapsLogger: AAPSLogger, private val aapsSchedulers: AapsSchedulers, private val config: Config, @@ -244,7 +244,7 @@ class AutomationPlugin @Inject constructor( } val enabled = constraintChecker.isAutomationEnabled() if (!enabled.value()) { - executionLog.add(enabled.getMostLimitedReasons(aapsLogger)) + executionLog.add(enabled.getMostLimitedReasons()) rxBus.send(EventAutomationUpdateGui()) 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 */ diff --git a/plugins/automation/src/test/java/info/nightscout/automation/AutomationEventTest.kt b/plugins/automation/src/test/java/info/nightscout/automation/AutomationEventTest.kt index 195baece55..84e723e73d 100644 --- a/plugins/automation/src/test/java/info/nightscout/automation/AutomationEventTest.kt +++ b/plugins/automation/src/test/java/info/nightscout/automation/AutomationEventTest.kt @@ -10,7 +10,6 @@ import info.nightscout.automation.triggers.TriggerConnectorTest import info.nightscout.automation.triggers.TriggerDummy import info.nightscout.interfaces.ConfigBuilder import info.nightscout.interfaces.aps.Loop -import info.nightscout.rx.bus.RxBus import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.sharedtests.TestBase import org.json.JSONObject @@ -36,7 +35,7 @@ class AutomationEventTest : TestBase() { it.loopPlugin = loopPlugin it.rh = rh it.configBuilder = configBuilder - it.rxBus = RxBus(aapsSchedulers, aapsLogger) + it.rxBus = rxBus } } } diff --git a/plugins/automation/src/test/java/info/nightscout/automation/BolusTimerImplTest.kt b/plugins/automation/src/test/java/info/nightscout/automation/BolusTimerImplTest.kt index c598d29860..a5d6a4a35d 100644 --- a/plugins/automation/src/test/java/info/nightscout/automation/BolusTimerImplTest.kt +++ b/plugins/automation/src/test/java/info/nightscout/automation/BolusTimerImplTest.kt @@ -10,13 +10,13 @@ import info.nightscout.core.utils.fabric.FabricPrivacy import info.nightscout.interfaces.Config import info.nightscout.interfaces.GlucoseUnit 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.profile.ProfileFunction -import info.nightscout.rx.bus.RxBus import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.utils.DateUtil +import info.nightscout.shared.utils.DateUtilImpl import info.nightscout.sharedtests.TestBase import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.BeforeEach @@ -32,8 +32,7 @@ class BolusTimerImplTest : TestBase() { @Mock lateinit var sp: SP @Mock lateinit var fabricPrivacy: FabricPrivacy @Mock lateinit var loop: Loop - @Mock lateinit var rxBus: RxBus - @Mock lateinit var constraintChecker: Constraints + @Mock lateinit var constraintChecker: ConstraintsChecker @Mock lateinit var config: Config @Mock lateinit var locationServiceHelper: LocationServiceHelper @Mock lateinit var activePlugin: ActivePlugin @@ -49,16 +48,17 @@ class BolusTimerImplTest : TestBase() { } } private lateinit var dateUtil: DateUtil - private lateinit var automationPlugin: AutomationPlugin @BeforeEach fun init() { Mockito.`when`(rh.gs(anyInt())).thenReturn("") Mockito.`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL) - dateUtil = DateUtil(context) - automationPlugin = AutomationPlugin(injector, rh, context, sp, fabricPrivacy, loop, rxBus, constraintChecker, aapsLogger, aapsSchedulers, config, locationServiceHelper, dateUtil, - activePlugin, timerUtil) + dateUtil = DateUtilImpl(context) + automationPlugin = AutomationPlugin( + injector, rh, context, sp, fabricPrivacy, loop, rxBus, constraintChecker, aapsLogger, aapsSchedulers, config, locationServiceHelper, dateUtil, + activePlugin, timerUtil + ) } @Test diff --git a/plugins/automation/src/test/java/info/nightscout/automation/CarbTimerImplTest.kt b/plugins/automation/src/test/java/info/nightscout/automation/CarbTimerImplTest.kt index ab6416eb4d..4d4ca8d8c3 100644 --- a/plugins/automation/src/test/java/info/nightscout/automation/CarbTimerImplTest.kt +++ b/plugins/automation/src/test/java/info/nightscout/automation/CarbTimerImplTest.kt @@ -10,13 +10,13 @@ import info.nightscout.core.utils.fabric.FabricPrivacy import info.nightscout.interfaces.Config import info.nightscout.interfaces.GlucoseUnit 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.profile.ProfileFunction -import info.nightscout.rx.bus.RxBus import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.utils.DateUtil +import info.nightscout.shared.utils.DateUtilImpl import info.nightscout.sharedtests.TestBase import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.BeforeEach @@ -33,8 +33,7 @@ class CarbTimerImplTest : TestBase() { @Mock lateinit var sp: SP @Mock lateinit var fabricPrivacy: FabricPrivacy @Mock lateinit var loop: Loop - @Mock lateinit var rxBus: RxBus - @Mock lateinit var constraintChecker: Constraints + @Mock lateinit var constraintChecker: ConstraintsChecker @Mock lateinit var config: Config @Mock lateinit var locationServiceHelper: LocationServiceHelper @Mock lateinit var activePlugin: ActivePlugin @@ -57,7 +56,7 @@ class CarbTimerImplTest : TestBase() { fun init() { Mockito.`when`(rh.gs(anyInt())).thenReturn("") Mockito.`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL) - dateUtil = DateUtil(context) + dateUtil = DateUtilImpl(context) timerUtil = TimerUtil(context) automationPlugin = AutomationPlugin( injector, rh, context, sp, fabricPrivacy, loop, rxBus, constraintChecker, aapsLogger, aapsSchedulers, config, locationServiceHelper, dateUtil, diff --git a/plugins/automation/src/test/java/info/nightscout/automation/actions/ActionAlarmTest.kt b/plugins/automation/src/test/java/info/nightscout/automation/actions/ActionAlarmTest.kt index 11b7cc8518..b4ff42be96 100644 --- a/plugins/automation/src/test/java/info/nightscout/automation/actions/ActionAlarmTest.kt +++ b/plugins/automation/src/test/java/info/nightscout/automation/actions/ActionAlarmTest.kt @@ -9,7 +9,6 @@ import info.nightscout.automation.ui.TimerUtil import info.nightscout.interfaces.Config import info.nightscout.interfaces.pump.PumpEnactResult import info.nightscout.interfaces.queue.Callback -import info.nightscout.rx.bus.RxBus import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.utils.DateUtil import info.nightscout.sharedtests.TestBase @@ -23,7 +22,6 @@ import org.mockito.Mockito.`when` class ActionAlarmTest : TestBase() { @Mock lateinit var rh: ResourceHelper - @Mock lateinit var rxBus: RxBus @Mock lateinit var context: Context @Mock lateinit var dateUtil: DateUtil @Mock lateinit var config: Config diff --git a/plugins/automation/src/test/java/info/nightscout/automation/actions/ActionNotificationTest.kt b/plugins/automation/src/test/java/info/nightscout/automation/actions/ActionNotificationTest.kt index a8fc633ab6..1cf9a096c7 100644 --- a/plugins/automation/src/test/java/info/nightscout/automation/actions/ActionNotificationTest.kt +++ b/plugins/automation/src/test/java/info/nightscout/automation/actions/ActionNotificationTest.kt @@ -26,7 +26,7 @@ class ActionNotificationTest : TestBase() { @Mock lateinit var rh: ResourceHelper @Mock lateinit var context: Context - @Mock lateinit var rxBus: RxBus + @Mock lateinit var rxBusMocked: RxBus @Mock lateinit var repository: AppRepository private lateinit var sut: ActionNotification @@ -34,7 +34,7 @@ class ActionNotificationTest : TestBase() { AndroidInjector { if (it is ActionNotification) { it.rh = rh - it.rxBus = rxBus + it.rxBus = rxBusMocked it.repository = repository } if (it is PumpEnactResult) { @@ -78,7 +78,7 @@ class ActionNotificationTest : TestBase() { 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)) } diff --git a/plugins/automation/src/test/java/info/nightscout/automation/actions/ActionsTestBase.kt b/plugins/automation/src/test/java/info/nightscout/automation/actions/ActionsTestBase.kt index 1e5ede19a8..0976da4cc7 100644 --- a/plugins/automation/src/test/java/info/nightscout/automation/actions/ActionsTestBase.kt +++ b/plugins/automation/src/test/java/info/nightscout/automation/actions/ActionsTestBase.kt @@ -3,29 +3,24 @@ package info.nightscout.automation.actions import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector 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.impl.AppRepository import info.nightscout.interfaces.ConfigBuilder import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.aps.Loop import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.iob.IobCobCalculator import info.nightscout.interfaces.logging.UserEntryLogger import info.nightscout.interfaces.plugin.PluginBase import info.nightscout.interfaces.plugin.PluginDescription import info.nightscout.interfaces.plugin.PluginType import info.nightscout.interfaces.profile.Profile -import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.profile.ProfileSource -import info.nightscout.interfaces.pump.Pump import info.nightscout.interfaces.pump.PumpEnactResult import info.nightscout.interfaces.queue.CommandQueue -import info.nightscout.interfaces.receivers.ReceiverStatusStore import info.nightscout.interfaces.smsCommunicator.SmsCommunicator import info.nightscout.rx.logging.AAPSLogger import info.nightscout.shared.interfaces.ResourceHelper -import info.nightscout.shared.utils.DateUtil import info.nightscout.sharedtests.TestBaseWithProfile import org.junit.jupiter.api.BeforeEach import org.mockito.Mock @@ -45,7 +40,7 @@ ActionsTestBase : TestBaseWithProfile() { private var suspended = false override var lastRun: Loop.LastRun? = Loop.LastRun() - override var closedLoopEnabled: Constraint? = Constraint(true) + override var closedLoopEnabled: Constraint? = ConstraintObject(true, injector) override val isSuspended: Boolean = suspended override val isLGS: Boolean = false override val isSuperBolus: Boolean = false @@ -174,6 +169,9 @@ ActionsTestBase : TestBaseWithProfile() { it.rh = rh it.aapsLogger = aapsLogger } + if (it is ConstraintObject<*>) { + it.aapsLogger = aapsLogger + } } } diff --git a/plugins/automation/src/test/java/info/nightscout/automation/triggers/TriggerTestBase.kt b/plugins/automation/src/test/java/info/nightscout/automation/triggers/TriggerTestBase.kt index 21aed46957..825a61499a 100644 --- a/plugins/automation/src/test/java/info/nightscout/automation/triggers/TriggerTestBase.kt +++ b/plugins/automation/src/test/java/info/nightscout/automation/triggers/TriggerTestBase.kt @@ -8,7 +8,6 @@ import info.nightscout.database.impl.AppRepository import info.nightscout.implementation.iob.GlucoseStatusProviderImpl import info.nightscout.interfaces.aps.AutosensDataStore import info.nightscout.interfaces.receivers.ReceiverStatusStore -import info.nightscout.rx.bus.RxBus import info.nightscout.sharedtests.TestBaseWithProfile import org.junit.jupiter.api.BeforeEach import org.mockito.Mock @@ -31,7 +30,7 @@ open class TriggerTestBase : TestBaseWithProfile() { AndroidInjector { if (it is Trigger) { it.aapsLogger = aapsLogger - it.rxBus = RxBus(aapsSchedulers, aapsLogger) + it.rxBus = rxBus it.rh = rh it.profileFunction = profileFunction it.sp = sp diff --git a/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/ConstraintsImpl.kt b/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/ConstraintsCheckerImpl.kt similarity index 57% rename from plugins/constraints/src/main/java/info/nightscout/plugins/constraints/ConstraintsImpl.kt rename to plugins/constraints/src/main/java/info/nightscout/plugins/constraints/ConstraintsCheckerImpl.kt index 990e860a28..09b1688ec8 100644 --- a/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/ConstraintsImpl.kt +++ b/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/ConstraintsCheckerImpl.kt @@ -1,109 +1,135 @@ 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.Constraints +import info.nightscout.interfaces.constraints.ConstraintsChecker +import info.nightscout.interfaces.constraints.PluginConstraints import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.profile.Profile import javax.inject.Inject import javax.inject.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 = isLoopInvocationAllowed(ConstraintObject(true, injector)) override fun isLoopInvocationAllowed(value: Constraint): Constraint { - val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java) + val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java) for (p in constraintsPlugins) { - val constraint = p as Constraints + val constraint = p as PluginConstraints if (!p.isEnabled()) continue constraint.isLoopInvocationAllowed(value) } return value } + override fun isClosedLoopAllowed(): Constraint = isClosedLoopAllowed(ConstraintObject(true, injector)) + override fun isClosedLoopAllowed(value: Constraint): Constraint { - val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java) + val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java) for (p in constraintsPlugins) { - val constraint = p as Constraints + val constraint = p as PluginConstraints if (!p.isEnabled()) continue constraint.isClosedLoopAllowed(value) } return value } + override fun isLgsAllowed(): Constraint = isLgsAllowed(ConstraintObject(true, injector)) + override fun isLgsAllowed(value: Constraint): Constraint { - val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java) + val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java) for (p in constraintsPlugins) { - val constraint = p as Constraints + val constraint = p as PluginConstraints if (!p.isEnabled()) continue constraint.isLgsAllowed(value) } return value } + override fun isAutosensModeEnabled(): Constraint = isAutosensModeEnabled(ConstraintObject(true, injector)) + override fun isAutosensModeEnabled(value: Constraint): Constraint { - val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java) + val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java) for (p in constraintsPlugins) { - val constraint = p as Constraints + val constraint = p as PluginConstraints if (!p.isEnabled()) continue constraint.isAutosensModeEnabled(value) } return value } + override fun isSMBModeEnabled(): Constraint = isSMBModeEnabled(ConstraintObject(true, injector)) + override fun isSMBModeEnabled(value: Constraint): Constraint { - val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java) + val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java) for (p in constraintsPlugins) { - val constraint = p as Constraints + val constraint = p as PluginConstraints if (!p.isEnabled()) continue constraint.isSMBModeEnabled(value) } return value } + override fun isDynIsfModeEnabled(): Constraint = isDynIsfModeEnabled(ConstraintObject(true, injector)) + override fun isDynIsfModeEnabled(value: Constraint): Constraint { - val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java) + val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java) for (p in constraintsPlugins) { - val constraint = p as Constraints + val constraint = p as PluginConstraints if (!p.isEnabled()) continue constraint.isDynIsfModeEnabled(value) } return value } + override fun isUAMEnabled(): Constraint = isUAMEnabled(ConstraintObject(true, injector)) + override fun isUAMEnabled(value: Constraint): Constraint { - val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java) + val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java) for (p in constraintsPlugins) { - val constraint = p as Constraints + val constraint = p as PluginConstraints if (!p.isEnabled()) continue constraint.isUAMEnabled(value) } return value } + override fun isAdvancedFilteringEnabled(): Constraint = isAdvancedFilteringEnabled(ConstraintObject(true, injector)) + override fun isAdvancedFilteringEnabled(value: Constraint): Constraint { - val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java) + val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java) for (p in constraintsPlugins) { - val constraint = p as Constraints + val constraint = p as PluginConstraints if (!p.isEnabled()) continue constraint.isAdvancedFilteringEnabled(value) } return value } + override fun isSuperBolusEnabled(): Constraint = isSuperBolusEnabled(ConstraintObject(true, injector)) + override fun isSuperBolusEnabled(value: Constraint): Constraint { - val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java) + val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java) for (p in constraintsPlugins) { - val constraint = p as Constraints + val constraint = p as PluginConstraints if (!p.isEnabled()) continue constraint.isSuperBolusEnabled(value) } return value } + override fun isAutomationEnabled(): Constraint = isAutomationEnabled(ConstraintObject(true, injector)) + override fun applyBasalConstraints(absoluteRate: Constraint, profile: Profile): Constraint { - val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java) + val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java) for (p in constraintsPlugins) { - val constraint = p as Constraints + val constraint = p as PluginConstraints if (!p.isEnabled()) continue constraint.applyBasalConstraints(absoluteRate, profile) } @@ -111,9 +137,9 @@ class ConstraintsImpl @Inject constructor(private val activePlugin: ActivePlugin } override fun applyBasalPercentConstraints(percentRate: Constraint, profile: Profile): Constraint { - val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java) + val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java) for (p in constraintsPlugins) { - val constrain = p as Constraints + val constrain = p as PluginConstraints if (!p.isEnabled()) continue constrain.applyBasalPercentConstraints(percentRate, profile) } @@ -121,9 +147,9 @@ class ConstraintsImpl @Inject constructor(private val activePlugin: ActivePlugin } override fun applyBolusConstraints(insulin: Constraint): Constraint { - val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java) + val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java) for (p in constraintsPlugins) { - val constrain = p as Constraints + val constrain = p as PluginConstraints if (!p.isEnabled()) continue constrain.applyBolusConstraints(insulin) } @@ -131,9 +157,9 @@ class ConstraintsImpl @Inject constructor(private val activePlugin: ActivePlugin } override fun applyExtendedBolusConstraints(insulin: Constraint): Constraint { - val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java) + val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java) for (p in constraintsPlugins) { - val constrain = p as Constraints + val constrain = p as PluginConstraints if (!p.isEnabled()) continue constrain.applyExtendedBolusConstraints(insulin) } @@ -141,9 +167,9 @@ class ConstraintsImpl @Inject constructor(private val activePlugin: ActivePlugin } override fun applyCarbsConstraints(carbs: Constraint): Constraint { - val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java) + val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java) for (p in constraintsPlugins) { - val constrain = p as Constraints + val constrain = p as PluginConstraints if (!p.isEnabled()) continue constrain.applyCarbsConstraints(carbs) } @@ -151,9 +177,9 @@ class ConstraintsImpl @Inject constructor(private val activePlugin: ActivePlugin } override fun applyMaxIOBConstraints(maxIob: Constraint): Constraint { - val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java) + val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java) for (p in constraintsPlugins) { - val constrain = p as Constraints + val constrain = p as PluginConstraints if (!p.isEnabled()) continue constrain.applyMaxIOBConstraints(maxIob) } @@ -161,12 +187,34 @@ class ConstraintsImpl @Inject constructor(private val activePlugin: ActivePlugin } override fun isAutomationEnabled(value: Constraint): Constraint { - val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java) + val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java) for (p in constraintsPlugins) { - val constraint = p as Constraints + val constraint = p as PluginConstraints if (!p.isEnabled()) continue constraint.isAutomationEnabled(value) } return value } + + /* + * Determine max values by walking through all constraints + */ + + override fun getMaxBasalAllowed(profile: Profile): Constraint = + applyBasalConstraints(ConstraintObject(Double.MAX_VALUE, injector), profile) + + override fun getMaxBasalPercentAllowed(profile: Profile): Constraint = + applyBasalPercentConstraints(ConstraintObject(Int.MAX_VALUE, injector), profile) + + override fun getMaxBolusAllowed(): Constraint = + applyBolusConstraints(ConstraintObject(Double.MAX_VALUE, injector)) + + override fun getMaxExtendedBolusAllowed(): Constraint = + applyExtendedBolusConstraints(ConstraintObject(Double.MAX_VALUE, injector)) + + override fun getMaxCarbsAllowed(): Constraint = + applyCarbsConstraints(ConstraintObject(Int.MAX_VALUE, injector)) + + override fun getMaxIOBAllowed(): Constraint = + applyMaxIOBConstraints(ConstraintObject(Double.MAX_VALUE, injector)) } \ No newline at end of file diff --git a/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/bgQualityCheck/BgQualityCheckPlugin.kt b/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/bgQualityCheck/BgQualityCheckPlugin.kt index 13f92597cc..3e2a9adf07 100644 --- a/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/bgQualityCheck/BgQualityCheckPlugin.kt +++ b/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/bgQualityCheck/BgQualityCheckPlugin.kt @@ -5,7 +5,7 @@ import dagger.android.HasAndroidInjector import info.nightscout.core.utils.fabric.FabricPrivacy import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck 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.plugin.ActivePlugin import info.nightscout.interfaces.plugin.PluginBase @@ -48,7 +48,7 @@ class BgQualityCheckPlugin @Inject constructor( .showInList(false) .pluginName(R.string.bg_quality), aapsLogger, rh, injector -), Constraints, BgQualityCheck { +), PluginConstraints, BgQualityCheck { private var disposable: CompositeDisposable = CompositeDisposable() @@ -71,7 +71,7 @@ class BgQualityCheckPlugin @Inject constructor( // Fallback to LGS if BG values are doubled override fun applyMaxIOBConstraints(maxIob: Constraint): Constraint = 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 maxIob diff --git a/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/di/PluginsConstraintsModule.kt b/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/di/PluginsConstraintsModule.kt index 3fbc067aa2..f212ea58de 100644 --- a/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/di/PluginsConstraintsModule.kt +++ b/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/di/PluginsConstraintsModule.kt @@ -3,9 +3,9 @@ package info.nightscout.plugins.constraints.di import dagger.Binds import dagger.Module 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.plugins.constraints.ConstraintsImpl +import info.nightscout.plugins.constraints.ConstraintsCheckerImpl import info.nightscout.plugins.constraints.bgQualityCheck.BgQualityCheckPlugin import info.nightscout.plugins.constraints.versionChecker.VersionCheckerUtilsImpl @@ -24,6 +24,6 @@ abstract class PluginsConstraintsModule { @Binds fun bindVersionCheckerUtils(versionCheckerUtils: VersionCheckerUtilsImpl): VersionCheckerUtils @Binds fun bindBgQualityCheck(bgQualityCheck: BgQualityCheckPlugin): BgQualityCheck - @Binds fun bindsConstraints(constraintsImpl: ConstraintsImpl): Constraints + @Binds fun bindsConstraintChecker(constraintsCheckerImpl: ConstraintsCheckerImpl): ConstraintsChecker } } \ No newline at end of file diff --git a/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/dstHelper/DstHelperPlugin.kt b/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/dstHelper/DstHelperPlugin.kt index ba7293a6ee..d51b2d833e 100644 --- a/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/dstHelper/DstHelperPlugin.kt +++ b/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/dstHelper/DstHelperPlugin.kt @@ -3,7 +3,7 @@ package info.nightscout.plugins.constraints.dstHelper import dagger.android.HasAndroidInjector import info.nightscout.interfaces.aps.Loop 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.plugin.ActivePlugin import info.nightscout.interfaces.plugin.PluginBase @@ -35,7 +35,7 @@ class DstHelperPlugin @Inject constructor( .showInList(false) .pluginName(R.string.dst_plugin_name), aapsLogger, rh, injector -), Constraints { +), PluginConstraints { companion object { @@ -74,7 +74,7 @@ class DstHelperPlugin @Inject constructor( } else { 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 } diff --git a/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/objectives/ObjectivesPlugin.kt b/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/objectives/ObjectivesPlugin.kt index d1aa0a557c..9fec153972 100644 --- a/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/objectives/ObjectivesPlugin.kt +++ b/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/objectives/ObjectivesPlugin.kt @@ -3,7 +3,6 @@ package info.nightscout.plugins.constraints.objectives import dagger.android.HasAndroidInjector import info.nightscout.interfaces.Config import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints import info.nightscout.interfaces.constraints.Objectives import info.nightscout.interfaces.constraints.Objectives.Companion.AUTOSENS_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.MAXIOB_ZERO_CL_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.PluginBase import info.nightscout.interfaces.plugin.PluginDescription @@ -54,7 +54,7 @@ class ObjectivesPlugin @Inject constructor( .shortName(R.string.objectives_shortname) .description(R.string.description_objectives), aapsLogger, rh, injector -), Constraints, Objectives { +), PluginConstraints, Objectives { var objectives: MutableList = ArrayList() @@ -112,49 +112,49 @@ class ObjectivesPlugin @Inject constructor( */ override fun isLoopInvocationAllowed(value: Constraint): Constraint { 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 } override fun isLgsAllowed(value: Constraint): Constraint { 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 } override fun isClosedLoopAllowed(value: Constraint): Constraint { 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 } override fun isAutosensModeEnabled(value: Constraint): Constraint { 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 } override fun isSMBModeEnabled(value: Constraint): Constraint { 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 } override fun isDynIsfModeEnabled(value: Constraint): Constraint { 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 } override fun applyMaxIOBConstraints(maxIob: Constraint): Constraint { 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 } override fun isAutomationEnabled(value: Constraint): Constraint { 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 } diff --git a/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/objectives/objectives/Objective4.kt b/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/objectives/objectives/Objective4.kt index a1398fe8ef..49c035bb2f 100644 --- a/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/objectives/objectives/Objective4.kt +++ b/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/objectives/objectives/Objective4.kt @@ -1,9 +1,8 @@ package info.nightscout.plugins.constraints.objectives.objectives import dagger.android.HasAndroidInjector -import info.nightscout.interfaces.Constants -import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.core.constraints.ConstraintObject +import info.nightscout.interfaces.constraints.PluginConstraints import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.profile.ProfileFunction 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 activePlugin: ActivePlugin + init { tasks.add( object : Task(this, R.string.objectives_maxbasal_gate) { override fun isCompleted(): Boolean { 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() return maxBasalSet.value() > 2.8 * maxDailyBasal } diff --git a/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/objectives/objectives/Objective5.kt b/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/objectives/objectives/Objective5.kt index d73cd22a2f..65dbe484e8 100644 --- a/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/objectives/objectives/Objective5.kt +++ b/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/objectives/objectives/Objective5.kt @@ -1,7 +1,7 @@ package info.nightscout.plugins.constraints.objectives.objectives 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.safety.SafetyPlugin import info.nightscout.shared.utils.T @@ -17,7 +17,7 @@ class Objective5(injector: HasAndroidInjector) : Objective(injector, "maxiobzero tasks.add( object : Task(this, R.string.closedmodeenabled) { override fun isCompleted(): Boolean { - val closedLoopEnabled = Constraint(true) + val closedLoopEnabled = ConstraintObject(true, injector) safetyPlugin.isClosedLoopAllowed(closedLoopEnabled) return closedLoopEnabled.value() } diff --git a/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/objectives/objectives/Objective6.kt b/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/objectives/objectives/Objective6.kt index a9030b8c2c..0b0b586b5d 100644 --- a/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/objectives/objectives/Objective6.kt +++ b/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/objectives/objectives/Objective6.kt @@ -2,7 +2,7 @@ package info.nightscout.plugins.constraints.objectives.objectives import dagger.android.HasAndroidInjector 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.shared.utils.T import javax.inject.Inject @@ -10,7 +10,7 @@ import javax.inject.Inject @Suppress("SpellCheckingInspection") 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 { tasks.add(MinimumDurationTask(this, T.days(1).msecs())) diff --git a/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/phoneChecker/PhoneCheckerPlugin.kt b/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/phoneChecker/PhoneCheckerPlugin.kt index 689bdd57a0..bab63a246d 100644 --- a/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/phoneChecker/PhoneCheckerPlugin.kt +++ b/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/phoneChecker/PhoneCheckerPlugin.kt @@ -4,7 +4,7 @@ import android.content.Context import android.os.Build import com.scottyab.rootbeer.RootBeer 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.PluginDescription import info.nightscout.interfaces.plugin.PluginType @@ -22,13 +22,13 @@ class PhoneCheckerPlugin @Inject constructor( private val context: Context ) : PluginBase( PluginDescription() - .mainType(PluginType.CONSTRAINTS) - .neverVisible(true) - .alwaysEnabled(true) - .showInList(false) - .pluginName(R.string.phone_checker), + .mainType(PluginType.CONSTRAINTS) + .neverVisible(true) + .alwaysEnabled(true) + .showInList(false) + .pluginName(R.string.phone_checker), aapsLogger, rh, injector -), Constraints { +), PluginConstraints { var phoneRooted: Boolean = false var devMode: Boolean = false @@ -36,8 +36,10 @@ class PhoneCheckerPlugin @Inject constructor( val manufacturer: String = Build.MANUFACTURER private fun isDevModeEnabled(): Boolean { - return android.provider.Settings.Secure.getInt(context.contentResolver, - android.provider.Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0 + return android.provider.Settings.Secure.getInt( + context.contentResolver, + android.provider.Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0 + ) != 0 } override fun onStart() { diff --git a/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/safety/SafetyPlugin.kt b/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/safety/SafetyPlugin.kt index 3c104f31e0..1ce7e85d93 100644 --- a/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/safety/SafetyPlugin.kt +++ b/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/safety/SafetyPlugin.kt @@ -1,6 +1,7 @@ package info.nightscout.plugins.constraints.safety import dagger.android.HasAndroidInjector +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.core.utils.extensions.putDouble import info.nightscout.core.utils.extensions.putInt 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.Config 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.iob.IobCobCalculator import info.nightscout.interfaces.notifications.Notification @@ -39,7 +41,7 @@ class SafetyPlugin @Inject constructor( aapsLogger: AAPSLogger, rh: ResourceHelper, private val sp: SP, - private val constraintChecker: Constraints, + private val constraintChecker: ConstraintsChecker, private val activePlugin: ActivePlugin, private val hardLimits: HardLimits, private val config: Config, @@ -56,57 +58,57 @@ class SafetyPlugin @Inject constructor( .pluginName(R.string.safety) .preferencesId(R.xml.pref_safety), aapsLogger, rh, injector -), Constraints, Safety { +), PluginConstraints, Safety { /** * Constraints interface */ override fun isLoopInvocationAllowed(value: Constraint): Constraint { - 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 } override fun isClosedLoopAllowed(value: Constraint): Constraint { 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 (value.value()) { 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 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 } override fun isSMBModeEnabled(value: Constraint): Constraint { 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 } override fun isAdvancedFilteringEnabled(value: Constraint): Constraint { 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 } override fun applyBasalConstraints(absoluteRate: Constraint, profile: Profile): Constraint { - 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.setIfSmaller(aapsLogger, hardLimits.maxBasal(), rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, hardLimits.maxBasal(), rh.gs(R.string.hardlimit)), 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(hardLimits.maxBasal(), rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, hardLimits.maxBasal(), rh.gs(R.string.hardlimit)), this) val pump = activePlugin.activePump // check for pump max if (pump.pumpDescription.tempBasalStyle == PumpDescription.ABSOLUTE) { 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 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 } @@ -119,52 +121,58 @@ class SafetyPlugin @Inject constructor( currentBasal ) + " U/h", this ) - val absoluteConstraint = Constraint(absoluteRate) + val absoluteConstraint = ConstraintObject(absoluteRate, injector) applyBasalConstraints(absoluteConstraint, profile) percentRate.copyReasons(absoluteConstraint) val pump = activePlugin.activePump 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() - percentRate.set(aapsLogger, percentRateAfterConst, rh.gs(info.nightscout.core.ui.R.string.limitingpercentrate, percentRateAfterConst, rh.gs(info.nightscout.core.ui.R.string.pumplimit)), this) + percentRateAfterConst = + 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) { 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 } override fun applyBolusConstraints(insulin: Constraint): Constraint { - 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) - insulin.setIfSmaller(aapsLogger, 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(maxBolus, rh.gs(info.nightscout.core.ui.R.string.limitingbolus, maxBolus, rh.gs(R.string.maxvalueinpreferences)), 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 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 } override fun applyExtendedBolusConstraints(insulin: Constraint): Constraint { - 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) - insulin.setIfSmaller(aapsLogger, 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(maxBolus, rh.gs(R.string.limitingextendedbolus, maxBolus, rh.gs(R.string.maxvalueinpreferences)), this) + insulin.setIfSmaller(hardLimits.maxBolus(), rh.gs(R.string.limitingextendedbolus, hardLimits.maxBolus(), rh.gs(R.string.hardlimit)), this) val pump = activePlugin.activePump 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 } override fun applyCarbsConstraints(carbs: Constraint): Constraint { - 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) - 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 } override fun applyMaxIOBConstraints(maxIob: Constraint): Constraint { 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 } diff --git a/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/signatureVerifier/SignatureVerifierPlugin.kt b/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/signatureVerifier/SignatureVerifierPlugin.kt index 6aaff96f09..97f966f3e1 100644 --- a/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/signatureVerifier/SignatureVerifierPlugin.kt +++ b/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/signatureVerifier/SignatureVerifierPlugin.kt @@ -6,7 +6,7 @@ import android.os.Handler import android.os.HandlerThread import dagger.android.HasAndroidInjector 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.plugin.PluginBase import info.nightscout.interfaces.plugin.PluginDescription @@ -54,7 +54,7 @@ class SignatureVerifierPlugin @Inject constructor( .showInList(false) .pluginName(R.string.signature_verifier), aapsLogger, rh, injector -), Constraints { +), PluginConstraints { 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): Constraint { if (hasIllegalSignature()) { showNotification() - value.set(aapsLogger, false) + value.set(false) } if (shouldDownloadCerts()) { handler.post { diff --git a/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/storage/StorageConstraintPlugin.kt b/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/storage/StorageConstraintPlugin.kt index 53d10c5296..677d1d7709 100644 --- a/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/storage/StorageConstraintPlugin.kt +++ b/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/storage/StorageConstraintPlugin.kt @@ -6,7 +6,7 @@ import dagger.android.HasAndroidInjector import info.nightscout.annotations.OpenForTesting import info.nightscout.interfaces.Constants 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.plugin.PluginBase import info.nightscout.interfaces.plugin.PluginDescription @@ -34,13 +34,13 @@ class StorageConstraintPlugin @Inject constructor( .showInList(false) .pluginName(R.string.storage), aapsLogger, rh, injector -), Constraints { +), PluginConstraints { override fun isClosedLoopAllowed(value: Constraint): Constraint { val diskFree = availableInternalMemorySize() if (diskFree < Constants.MINIMUM_FREE_SPACE) { 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) } return value diff --git a/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/versionChecker/VersionCheckerPlugin.kt b/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/versionChecker/VersionCheckerPlugin.kt index 5bf36f822d..b2f27e1b9a 100644 --- a/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/versionChecker/VersionCheckerPlugin.kt +++ b/plugins/constraints/src/main/java/info/nightscout/plugins/constraints/versionChecker/VersionCheckerPlugin.kt @@ -3,7 +3,7 @@ package info.nightscout.plugins.constraints.versionChecker import dagger.android.HasAndroidInjector import info.nightscout.interfaces.Config 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.plugin.PluginBase import info.nightscout.interfaces.plugin.PluginDescription @@ -40,7 +40,7 @@ class VersionCheckerPlugin @Inject constructor( .showInList(false) .pluginName(R.string.version_checker), aapsLogger, rh, injector -), Constraints { +), PluginConstraints { enum class GracePeriod(val warning: Long, val old: Long, val veryOld: Long) { RELEASE(30, 60, 90), @@ -64,16 +64,16 @@ class VersionCheckerPlugin @Inject constructor( checkWarning() versionCheckerUtils.triggerCheckVersion() 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) 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 } override fun applyMaxIOBConstraints(maxIob: Constraint): Constraint = 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 maxIob diff --git a/plugins/constraints/src/test/java/info/nightscout/plugins/constraints/bgQualityCheck/BgQualityCheckPluginTest.kt b/plugins/constraints/src/test/java/info/nightscout/plugins/constraints/bgQualityCheck/BgQualityCheckPluginTest.kt index c1e599c8f5..09e07728a2 100644 --- a/plugins/constraints/src/test/java/info/nightscout/plugins/constraints/bgQualityCheck/BgQualityCheckPluginTest.kt +++ b/plugins/constraints/src/test/java/info/nightscout/plugins/constraints/bgQualityCheck/BgQualityCheckPluginTest.kt @@ -2,16 +2,15 @@ package info.nightscout.plugins.constraints.bgQualityCheck import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.core.utils.fabric.FabricPrivacy import info.nightscout.database.entities.GlucoseValue import info.nightscout.interfaces.aps.AutosensDataStore import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck -import info.nightscout.interfaces.constraints.Constraint import info.nightscout.interfaces.iob.InMemoryGlucoseValue import info.nightscout.interfaces.iob.IobCobCalculator import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.plugins.constraints.R -import info.nightscout.rx.bus.RxBus import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.utils.DateUtil import info.nightscout.shared.utils.T @@ -35,7 +34,13 @@ class BgQualityCheckPluginTest : TestBase() { 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 autosensDataStore = AutosensDataStoreObject() @@ -46,7 +51,7 @@ class BgQualityCheckPluginTest : TestBase() { injector, aapsLogger, rh, - RxBus(aapsSchedulers, aapsLogger), + rxBus, iobCobCalculator, aapsSchedulers, fabricPrivacy, @@ -75,10 +80,46 @@ class BgQualityCheckPluginTest : TestBase() { Assertions.assertEquals(R.drawable.ic_baseline_warning_24_yellow, plugin.icon()) val superData: MutableList = 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(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)) + 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( + 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.lastUsed5minCalculation).thenReturn(true) @@ -205,16 +246,106 @@ class BgQualityCheckPluginTest : TestBase() { // Flat data Libre val flatData: MutableList = 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(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)) + 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( + 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`(iobCobCalculator.ads.lastBg()).thenReturn(InMemoryGlucoseValue(flatData[0])) @@ -224,16 +355,106 @@ class BgQualityCheckPluginTest : TestBase() { // Flat data Libre val flatDataDexcom: MutableList = 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(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)) + 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( + 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`(iobCobCalculator.ads.lastBg()).thenReturn(InMemoryGlucoseValue(flatDataDexcom[0])) @@ -243,19 +464,100 @@ class BgQualityCheckPluginTest : TestBase() { // not enough data val incompleteData: MutableList = 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(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)) + 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( + 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`(iobCobCalculator.ads.lastBg()).thenReturn(InMemoryGlucoseValue(incompleteData[0])) plugin.processBgData()// must be more than 5 values 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(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 = 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 + ) + ) plugin.processBgData() // must be at least 45 min old Assertions.assertNotEquals(BgQualityCheck.State.FLAT, plugin.state) } @@ -263,13 +565,13 @@ class BgQualityCheckPluginTest : TestBase() { @Test fun applyMaxIOBConstraintsTest() { 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 - 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 - 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 - 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) } } \ No newline at end of file diff --git a/plugins/constraints/src/test/java/info/nightscout/plugins/constraints/objectives/ObjectivesPluginTest.kt b/plugins/constraints/src/test/java/info/nightscout/plugins/constraints/objectives/ObjectivesPluginTest.kt index ea712ceea9..e668b07c09 100644 --- a/plugins/constraints/src/test/java/info/nightscout/plugins/constraints/objectives/ObjectivesPluginTest.kt +++ b/plugins/constraints/src/test/java/info/nightscout/plugins/constraints/objectives/ObjectivesPluginTest.kt @@ -2,8 +2,8 @@ package info.nightscout.plugins.constraints.objectives import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.interfaces.Config -import info.nightscout.interfaces.constraints.Constraint import info.nightscout.interfaces.constraints.Objectives import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.plugins.constraints.R @@ -35,6 +35,9 @@ class ObjectivesPluginTest : TestBase() { it.rh = rh it.dateUtil = dateUtil } + if (it is ConstraintObject<*>) { + it.aapsLogger = aapsLogger + } } } @@ -49,34 +52,30 @@ class ObjectivesPluginTest : TestBase() { @Test fun notStartedObjectivesShouldLimitLoopInvocation() { objectivesPlugin.objectives[Objectives.FIRST_OBJECTIVE].startedOn = 0 - var c = Constraint(true) - c = objectivesPlugin.isLoopInvocationAllowed(c) - Assertions.assertEquals("Objectives: Objective 1 not started", c.getReasons(aapsLogger)) + val c = objectivesPlugin.isLoopInvocationAllowed(ConstraintObject(true, injector)) + Assertions.assertEquals("Objectives: Objective 1 not started", c.getReasons()) Assertions.assertEquals(false, c.value()) objectivesPlugin.objectives[Objectives.FIRST_OBJECTIVE].startedOn = dateUtil.now() } @Test fun notStartedObjective6ShouldLimitClosedLoop() { objectivesPlugin.objectives[Objectives.MAXIOB_ZERO_CL_OBJECTIVE].startedOn = 0 - var c = Constraint(true) - c = objectivesPlugin.isClosedLoopAllowed(c) - Assertions.assertEquals(true, c.getReasons(aapsLogger).contains("Objective 6 not started")) + val c = objectivesPlugin.isClosedLoopAllowed(ConstraintObject(true, injector)) + Assertions.assertEquals(true, c.getReasons().contains("Objective 6 not started")) Assertions.assertEquals(false, c.value()) } @Test fun notStartedObjective8ShouldLimitAutosensMode() { objectivesPlugin.objectives[Objectives.AUTOSENS_OBJECTIVE].startedOn = 0 - var c = Constraint(true) - c = objectivesPlugin.isAutosensModeEnabled(c) - Assertions.assertEquals(true, c.getReasons(aapsLogger).contains("Objective 8 not started")) + val c = objectivesPlugin.isAutosensModeEnabled(ConstraintObject(true, injector)) + Assertions.assertEquals(true, c.getReasons().contains("Objective 8 not started")) Assertions.assertEquals(false, c.value()) } @Test fun notStartedObjective10ShouldLimitSMBMode() { objectivesPlugin.objectives[Objectives.SMB_OBJECTIVE].startedOn = 0 - var c = Constraint(true) - c = objectivesPlugin.isSMBModeEnabled(c) - Assertions.assertEquals(true, c.getReasons(aapsLogger).contains("Objective 9 not started")) + val c = objectivesPlugin.isSMBModeEnabled(ConstraintObject(true, injector)) + Assertions.assertEquals(true, c.getReasons().contains("Objective 9 not started")) Assertions.assertEquals(false, c.value()) } } \ No newline at end of file diff --git a/plugins/constraints/src/test/java/info/nightscout/plugins/constraints/storage/StorageConstraintPluginTest.kt b/plugins/constraints/src/test/java/info/nightscout/plugins/constraints/storage/StorageConstraintPluginTest.kt index 8e917a0652..51c8a130c9 100644 --- a/plugins/constraints/src/test/java/info/nightscout/plugins/constraints/storage/StorageConstraintPluginTest.kt +++ b/plugins/constraints/src/test/java/info/nightscout/plugins/constraints/storage/StorageConstraintPluginTest.kt @@ -2,7 +2,7 @@ package info.nightscout.plugins.constraints.storage import dagger.android.AndroidInjector 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.rx.logging.AAPSLogger import info.nightscout.shared.interfaces.ResourceHelper @@ -20,6 +20,13 @@ class StorageConstraintPluginTest : TestBase() { @Mock lateinit var rh: ResourceHelper @Mock lateinit var uiInteraction: UiInteraction + private val injector = HasAndroidInjector { + AndroidInjector { + if (it is ConstraintObject<*>) { + it.aapsLogger = aapsLogger + } + } + } private lateinit var storageConstraintPlugin: StorageConstraintPlugin @BeforeEach fun prepareMock() { @@ -42,9 +49,9 @@ class StorageConstraintPluginTest : TestBase() { val mocked = MockedStorageConstraintPlugin({ AndroidInjector { } }, aapsLogger, rh, uiInteraction) // Set free space under 200(Mb) to disable loop 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 mocked.memSize = 300L - Assertions.assertEquals(true, mocked.isClosedLoopAllowed(Constraint(true)).value()) + Assertions.assertEquals(true, mocked.isClosedLoopAllowed(ConstraintObject(true, injector)).value()) } } \ No newline at end of file diff --git a/plugins/insulin/src/test/java/info/nightscout/insulin/InsulinOrefFreePeakPluginTest.kt b/plugins/insulin/src/test/java/info/nightscout/insulin/InsulinOrefFreePeakPluginTest.kt index f9a2ae62dc..af3df55f01 100644 --- a/plugins/insulin/src/test/java/info/nightscout/insulin/InsulinOrefFreePeakPluginTest.kt +++ b/plugins/insulin/src/test/java/info/nightscout/insulin/InsulinOrefFreePeakPluginTest.kt @@ -7,7 +7,6 @@ import info.nightscout.interfaces.insulin.Insulin import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.ui.UiInteraction import info.nightscout.interfaces.utils.HardLimits -import info.nightscout.rx.bus.RxBus import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.sharedPreferences.SP import info.nightscout.sharedtests.TestBase @@ -29,7 +28,6 @@ class InsulinOrefFreePeakPluginTest : TestBase() { @Mock lateinit var sp: SP @Mock lateinit var rh: ResourceHelper - @Mock lateinit var rxBus: RxBus @Mock lateinit var profileFunction: ProfileFunction @Mock lateinit var config: Config @Mock lateinit var hardLimits: HardLimits diff --git a/plugins/main/src/main/java/info/nightscout/plugins/general/overview/OverviewFragment.kt b/plugins/main/src/main/java/info/nightscout/plugins/general/overview/OverviewFragment.kt index 0a19977f25..1157f7ee2a 100644 --- a/plugins/main/src/main/java/info/nightscout/plugins/general/overview/OverviewFragment.kt +++ b/plugins/main/src/main/java/info/nightscout/plugins/general/overview/OverviewFragment.kt @@ -27,6 +27,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import com.jjoe64.graphview.GraphView import dagger.android.HasAndroidInjector import dagger.android.support.DaggerFragment +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.core.extensions.directionToIcon import info.nightscout.core.graph.OverviewData 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.automation.Automation import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck -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.IobCobCalculator import info.nightscout.interfaces.logging.UserEntryLogger @@ -121,7 +121,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList @Inject lateinit var defaultValueHelper: DefaultValueHelper @Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var profileUtil: ProfileUtil - @Inject lateinit var constraintChecker: Constraints + @Inject lateinit var constraintChecker: ConstraintsChecker @Inject lateinit var statusLightHandler: StatusLightHandler @Inject lateinit var processedDeviceStatusData: ProcessedDeviceStatusData @Inject lateinit var nsSettingsStatus: NSSettingsStatus @@ -516,7 +516,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList binding.buttonsLayout.quickWizardButton.visibility = View.VISIBLE val wizard = quickWizardEntry.doCalc(profile, profileName, actualBg) 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 { 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)) diff --git a/plugins/main/src/main/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt b/plugins/main/src/main/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt index b05207344e..ea6a505ea8 100644 --- a/plugins/main/src/main/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt +++ b/plugins/main/src/main/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPlugin.kt @@ -11,6 +11,7 @@ import androidx.work.WorkerParameters import androidx.work.workDataOf import dagger.android.HasAndroidInjector import info.nightscout.annotations.OpenForTesting +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.core.events.EventNewNotification import info.nightscout.core.iob.generateCOBString import info.nightscout.core.iob.round @@ -34,8 +35,7 @@ import info.nightscout.interfaces.Constants import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.XDripBroadcast import info.nightscout.interfaces.aps.Loop -import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.iob.GlucoseStatusProvider import info.nightscout.interfaces.iob.IobCobCalculator import info.nightscout.interfaces.logging.UserEntryLogger @@ -91,7 +91,7 @@ class SmsCommunicatorPlugin @Inject constructor( private val smsManager: SmsManager?, private val aapsSchedulers: AapsSchedulers, private val sp: SP, - private val constraintChecker: Constraints, + private val constraintChecker: ConstraintsChecker, private val rxBus: RxBus, private val profileFunction: ProfileFunction, 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 (duration <= 0 || duration % durationStep != 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.sms_wrong_tbr_duration, durationStep))) else { - tempBasalPct = constraintChecker.applyBasalPercentConstraints(Constraint(tempBasalPct), profile).value() + tempBasalPct = constraintChecker.applyBasalPercentConstraints(ConstraintObject(tempBasalPct, injector), profile).value() val passCode = generatePassCode() val reply = rh.gs(R.string.smscommunicator_basal_pct_reply_with_code, tempBasalPct, duration, passCode) 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 (duration <= 0 || duration % durationStep != 0) sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.sms_wrong_tbr_duration, durationStep))) else { - tempBasal = constraintChecker.applyBasalConstraints(Constraint(tempBasal), profile).value() + tempBasal = constraintChecker.applyBasalConstraints(ConstraintObject(tempBasal, injector), profile).value() val passCode = generatePassCode() val reply = rh.gs(R.string.smscommunicator_basal_reply_with_code, tempBasal, duration, passCode) receivedSms.processed = true @@ -864,7 +864,7 @@ class SmsCommunicatorPlugin @Inject constructor( } else { var extended = SafeParse.stringToDouble(divided[1]) 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))) else { val passCode = generatePassCode() @@ -918,7 +918,7 @@ class SmsCommunicatorPlugin @Inject constructor( private fun processBOLUS(divided: Array, receivedSms: Sms) { var bolus = SafeParse.stringToDouble(divided[1]) 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) { sendSMS(Sms(receivedSms.phoneNumber, rh.gs(R.string.wrong_format))) } else if (bolus > 0.0) { @@ -1031,7 +1031,7 @@ class SmsCommunicatorPlugin @Inject constructor( 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))) else { val passCode = generatePassCode() diff --git a/plugins/main/src/main/java/info/nightscout/plugins/general/wear/wearintegration/DataHandlerMobile.kt b/plugins/main/src/main/java/info/nightscout/plugins/general/wear/wearintegration/DataHandlerMobile.kt index fbb7e0701a..55b368a20f 100644 --- a/plugins/main/src/main/java/info/nightscout/plugins/general/wear/wearintegration/DataHandlerMobile.kt +++ b/plugins/main/src/main/java/info/nightscout/plugins/general/wear/wearintegration/DataHandlerMobile.kt @@ -3,6 +3,7 @@ package info.nightscout.plugins.general.wear.wearintegration import android.app.NotificationManager import android.content.Context import dagger.android.HasAndroidInjector +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.core.extensions.convertedToAbsolute import info.nightscout.core.extensions.toStringShort import info.nightscout.core.extensions.valueToUnits @@ -33,8 +34,7 @@ import info.nightscout.interfaces.Config import info.nightscout.interfaces.Constants import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.aps.Loop -import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.db.PersistenceLayer import info.nightscout.interfaces.iob.GlucoseStatusProvider import info.nightscout.interfaces.iob.InMemoryGlucoseValue @@ -104,7 +104,7 @@ class DataHandlerMobile @Inject constructor( private val defaultValueHelper: DefaultValueHelper, private val trendCalculator: TrendCalculator, private val dateUtil: DateUtil, - private val constraintChecker: Constraints, + private val constraintChecker: ConstraintsChecker, private val uel: UserEntryLogger, private val activePlugin: ActivePlugin, private val commandQueue: CommandQueue, @@ -269,7 +269,7 @@ class DataHandlerMobile @Inject constructor( .observeOn(aapsSchedulers.io) .subscribe({ 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") sendError("aborting: previously applied constraint changed") } else @@ -383,7 +383,7 @@ class DataHandlerMobile @Inject constructor( return } val carbsBeforeConstraints = command.carbs - val carbsAfterConstraints = constraintChecker.applyCarbsConstraints(Constraint(carbsBeforeConstraints)).value() + val carbsAfterConstraints = constraintChecker.applyCarbsConstraints(ConstraintObject(carbsBeforeConstraints, injector)).value() if (carbsAfterConstraints - carbsBeforeConstraints != 0) { sendError(rh.gs(info.nightscout.core.ui.R.string.wizard_carbs_constraint)) return @@ -480,7 +480,7 @@ class DataHandlerMobile @Inject constructor( 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()) { sendError(rh.gs(info.nightscout.core.ui.R.string.wizard_carbs_constraint)) return @@ -506,8 +506,8 @@ class DataHandlerMobile @Inject constructor( } private fun handleBolusPreCheck(command: EventData.ActionBolusPreCheck) { - val insulinAfterConstraints = constraintChecker.applyBolusConstraints(Constraint(command.insulin)).value() - val carbsAfterConstraints = constraintChecker.applyCarbsConstraints(Constraint(command.carbs)).value() + val insulinAfterConstraints = constraintChecker.applyBolusConstraints(ConstraintObject(command.insulin, injector)).value() + val carbsAfterConstraints = constraintChecker.applyCarbsConstraints(ConstraintObject(command.carbs, injector)).value() val pump = activePlugin.activePump if (insulinAfterConstraints > 0 && (!pump.isInitialized() || pump.isSuspended() || loop.isDisconnected)) { 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) { 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) + "\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) @@ -558,7 +558,7 @@ class DataHandlerMobile @Inject constructor( 3 -> sp.getDouble("fill_button3", 0.0) 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) if (insulinAfterConstraints - amount != 0.0) message += "\n" + rh.gs(info.nightscout.core.ui.R.string.constraint_applied) rxBus.send( @@ -572,7 +572,7 @@ class DataHandlerMobile @Inject constructor( } 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) if (insulinAfterConstraints - command.insulin != 0.0) message += "\n" + rh.gs(info.nightscout.core.ui.R.string.constraint_applied) rxBus.send( diff --git a/plugins/main/src/test/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt b/plugins/main/src/test/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt index a591e04dc8..825555b7c8 100644 --- a/plugins/main/src/test/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt +++ b/plugins/main/src/test/java/info/nightscout/plugins/general/smsCommunicator/SmsCommunicatorPluginTest.kt @@ -4,6 +4,7 @@ import android.telephony.SmsManager import com.google.common.truth.Truth.assertThat import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.database.entities.GlucoseValue import info.nightscout.database.impl.AppRepository 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.aps.AutosensDataStore import info.nightscout.interfaces.aps.Loop -import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.iob.CobInfo import info.nightscout.interfaces.iob.InMemoryGlucoseValue import info.nightscout.interfaces.iob.IobTotal @@ -48,7 +48,7 @@ import org.mockito.invocation.InvocationOnMock @Suppress("SpellCheckingInspection") class SmsCommunicatorPluginTest : TestBaseWithProfile() { - @Mock lateinit var constraintChecker: Constraints + @Mock lateinit var constraintChecker: ConstraintsChecker @Mock lateinit var commandQueue: CommandQueue @Mock lateinit var loop: Loop @Mock lateinit var profileSource: ProfileSource @@ -62,6 +62,9 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { private var injector: HasAndroidInjector = HasAndroidInjector { AndroidInjector { + if (it is ConstraintObject<*>) { + it.aapsLogger = aapsLogger + } if (it is PumpEnactResult) { it.context = context } @@ -836,7 +839,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { smsCommunicatorPlugin.processSms(sms) 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.") - `when`(constraintChecker.applyBasalPercentConstraints(anyObject(), anyObject())).thenReturn(Constraint(20)) + `when`(constraintChecker.applyBasalPercentConstraints(anyObject(), anyObject())).thenReturn(ConstraintObject(20, injector)) //BASAL 20% 30 smsCommunicatorPlugin.messages = ArrayList() @@ -862,7 +865,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { smsCommunicatorPlugin.processSms(sms) 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.") - `when`(constraintChecker.applyBasalConstraints(anyObject(), anyObject())).thenReturn(Constraint(1.0)) + `when`(constraintChecker.applyBasalConstraints(anyObject(), anyObject())).thenReturn(ConstraintObject(1.0, injector)) //BASAL 1 20 smsCommunicatorPlugin.messages = ArrayList() @@ -870,7 +873,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { smsCommunicatorPlugin.processSms(sms) 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.") - `when`(constraintChecker.applyBasalConstraints(anyObject(), anyObject())).thenReturn(Constraint(1.0)) + `when`(constraintChecker.applyBasalConstraints(anyObject(), anyObject())).thenReturn(ConstraintObject(1.0, injector)) //BASAL 1 30 smsCommunicatorPlugin.messages = ArrayList() @@ -918,7 +921,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { smsCommunicatorPlugin.processSms(sms) assertThat(smsCommunicatorPlugin.messages[0].text).isEqualTo("EXTENDED a%") 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 smsCommunicatorPlugin.messages = ArrayList() @@ -955,7 +958,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { smsCommunicatorPlugin.processSms(sms) assertThat(smsCommunicatorPlugin.messages[0].text).isEqualTo("BOLUS") 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`(sp.getLong(R.string.key_smscommunicator_remote_bolus_min_distance, T.msecs(Constants.remoteBolusMinDistance).mins())).thenReturn(15L) //BOLUS 1 @@ -964,7 +967,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { smsCommunicatorPlugin.processSms(sms) assertThat(smsCommunicatorPlugin.messages[0].text).isEqualTo("BOLUS 1") 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) //BOLUS 0 @@ -980,8 +983,8 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { smsCommunicatorPlugin.processSms(sms) assertThat(smsCommunicatorPlugin.messages[0].text).isEqualTo("BOLUS a") assertThat(smsCommunicatorPlugin.messages[1].text).isEqualTo("Wrong format") - `when`(constraintChecker.applyExtendedBolusConstraints(anyObject())).thenReturn(Constraint(1.0)) - `when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(Constraint(1.0)) + `when`(constraintChecker.applyExtendedBolusConstraints(anyObject())).thenReturn(ConstraintObject(1.0, injector)) + `when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(ConstraintObject(1.0, injector)) //BOLUS 1 smsCommunicatorPlugin.messages = ArrayList() @@ -1078,7 +1081,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { smsCommunicatorPlugin.processSms(sms) assertThat(smsCommunicatorPlugin.messages[0].text).isEqualTo("CARBS") 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 smsCommunicatorPlugin.messages = ArrayList() @@ -1086,7 +1089,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() { smsCommunicatorPlugin.processSms(sms) assertThat(smsCommunicatorPlugin.messages[0].text).isEqualTo("CARBS 0") 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 smsCommunicatorPlugin.messages = ArrayList() diff --git a/plugins/main/src/test/java/info/nightscout/plugins/iob/AutosensDataStoreTest.kt b/plugins/main/src/test/java/info/nightscout/plugins/iob/AutosensDataStoreTest.kt index 56f3215545..e342e4eeb9 100644 --- a/plugins/main/src/test/java/info/nightscout/plugins/iob/AutosensDataStoreTest.kt +++ b/plugins/main/src/test/java/info/nightscout/plugins/iob/AutosensDataStoreTest.kt @@ -12,6 +12,7 @@ import info.nightscout.plugins.iob.iobCobCalculator.data.AutosensDataStoreObject import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.utils.DateUtil +import info.nightscout.shared.utils.DateUtilImpl import info.nightscout.shared.utils.T import info.nightscout.sharedtests.TestBase import org.junit.jupiter.api.Assertions @@ -46,7 +47,7 @@ class AutosensDataStoreTest : TestBase() { @BeforeEach fun mock() { - dateUtil = DateUtil(context) + dateUtil = DateUtilImpl(context) } @Test diff --git a/plugins/sensitivity/src/main/java/info/nightscout/sensitivity/SensitivityOref1Plugin.kt b/plugins/sensitivity/src/main/java/info/nightscout/sensitivity/SensitivityOref1Plugin.kt index f98681d3b8..d77c1de943 100644 --- a/plugins/sensitivity/src/main/java/info/nightscout/sensitivity/SensitivityOref1Plugin.kt +++ b/plugins/sensitivity/src/main/java/info/nightscout/sensitivity/SensitivityOref1Plugin.kt @@ -12,7 +12,7 @@ import info.nightscout.interfaces.aps.AutosensResult import info.nightscout.interfaces.aps.SMBDefaults import info.nightscout.interfaces.aps.Sensitivity.SensitivityType 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.PluginType import info.nightscout.interfaces.profile.ProfileFunction @@ -51,7 +51,7 @@ class SensitivityOref1Plugin @Inject constructor( .description(R.string.description_sensitivity_oref1) .setDefault(), injector, aapsLogger, rh, sp -), Constraints { +), PluginConstraints { override fun detectSensitivity(ads: AutosensDataStore, fromTime: Long, toTime: Long): AutosensResult { val profile = profileFunction.getProfile() @@ -260,7 +260,7 @@ class SensitivityOref1Plugin @Inject constructor( get() = SensitivityType.SENSITIVITY_OREF1 override fun isUAMEnabled(value: Constraint): Constraint { - 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 } } \ No newline at end of file diff --git a/plugins/sync/src/test/java/info/nightscout/plugins/sync/nsclient/ReceiverDelegateTest.kt b/plugins/sync/src/test/java/info/nightscout/plugins/sync/nsclient/ReceiverDelegateTest.kt index 3903925b52..ea9149f0c7 100644 --- a/plugins/sync/src/test/java/info/nightscout/plugins/sync/nsclient/ReceiverDelegateTest.kt +++ b/plugins/sync/src/test/java/info/nightscout/plugins/sync/nsclient/ReceiverDelegateTest.kt @@ -3,7 +3,6 @@ package info.nightscout.plugins.sync.nsclient import info.nightscout.core.utils.fabric.FabricPrivacy import info.nightscout.interfaces.receivers.ReceiverStatusStore import info.nightscout.plugins.sync.R -import info.nightscout.rx.bus.RxBus import info.nightscout.rx.events.EventChargingState import info.nightscout.rx.events.EventNetworkChange import info.nightscout.shared.interfaces.ResourceHelper @@ -20,7 +19,6 @@ class ReceiverDelegateTest : TestBase() { @Mock lateinit var sp: SP @Mock lateinit var rh: ResourceHelper @Mock lateinit var fabricPrivacy: FabricPrivacy - private val rxBus = RxBus(aapsSchedulers, aapsLogger) @Mock private lateinit var receiverStatusStore: ReceiverStatusStore private lateinit var sut: ReceiverDelegate diff --git a/plugins/sync/src/test/java/info/nightscout/plugins/sync/nsclientV3/workers/DataSyncWorkerTest.kt b/plugins/sync/src/test/java/info/nightscout/plugins/sync/nsclientV3/workers/DataSyncWorkerTest.kt index 18eab903ec..4173e6e8e6 100644 --- a/plugins/sync/src/test/java/info/nightscout/plugins/sync/nsclientV3/workers/DataSyncWorkerTest.kt +++ b/plugins/sync/src/test/java/info/nightscout/plugins/sync/nsclientV3/workers/DataSyncWorkerTest.kt @@ -10,7 +10,6 @@ import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.sync.NsClient import info.nightscout.plugins.sync.nsclientV3.DataSyncSelectorV3 import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin -import info.nightscout.rx.bus.RxBus import info.nightscout.sharedtests.TestBase import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest @@ -30,7 +29,6 @@ internal class DataSyncWorkerTest : TestBase() { @Mock lateinit var dataSyncSelectorV3: DataSyncSelectorV3 @Mock lateinit var activePlugin: ActivePlugin @Mock lateinit var nsClient: NsClient - @Mock lateinit var rxBus: RxBus @Mock lateinit var nsClientV3Plugin: NSClientV3Plugin @Mock lateinit var context: ContextWithInjector diff --git a/plugins/sync/src/test/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadBgWorkerTest.kt b/plugins/sync/src/test/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadBgWorkerTest.kt index 917dd76573..6e88ae34d7 100644 --- a/plugins/sync/src/test/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadBgWorkerTest.kt +++ b/plugins/sync/src/test/java/info/nightscout/plugins/sync/nsclientV3/workers/LoadBgWorkerTest.kt @@ -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.NSClientV3Plugin import info.nightscout.plugins.sync.nsclientV3.extensions.toNSSvgV3 -import info.nightscout.rx.bus.RxBus import info.nightscout.sdk.interfaces.NSAndroidClient import info.nightscout.sdk.remotemodel.LastModified import info.nightscout.shared.interfaces.ResourceHelper @@ -66,7 +65,6 @@ internal class LoadBgWorkerTest : TestBase() { @Mock lateinit var nsIncomingDataProcessor: NsIncomingDataProcessor @Mock lateinit var context: ContextWithInjector - private val rxBus: RxBus = RxBus(aapsSchedulers, aapsLogger) private lateinit var nsClientV3Plugin: NSClientV3Plugin private lateinit var receiverDelegate: ReceiverDelegate private lateinit var dataWorkerStorage: DataWorkerStorage diff --git a/pump/combo/src/main/java/info/nightscout/pump/combo/ComboPlugin.java b/pump/combo/src/main/java/info/nightscout/pump/combo/ComboPlugin.java index e880a9684b..60076f31cd 100644 --- a/pump/combo/src/main/java/info/nightscout/pump/combo/ComboPlugin.java +++ b/pump/combo/src/main/java/info/nightscout/pump/combo/ComboPlugin.java @@ -22,7 +22,7 @@ import javax.inject.Singleton; import dagger.android.HasAndroidInjector; import info.nightscout.core.utils.fabric.InstanceId; 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.plugin.PluginDescription; import info.nightscout.interfaces.plugin.PluginType; @@ -86,23 +86,41 @@ import info.nightscout.shared.utils.T; * Created by mike on 05.08.2016. */ @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 private final ProfileFunction profileFunction; private final SP sp; - private RxBus rxBus; private final CommandQueue commandQueue; private final PumpSync pumpSync; private final DateUtil dateUtil; private final RuffyCommands ruffyScripter; private final UiInteraction uiInteraction; - - private final static PumpDescription pumpDescription = new PumpDescription(); - - - @NonNull - private static final ComboPump pump = new ComboPump(); - + private RxBus rxBus; + 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); + }; /** * 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. */ private volatile boolean cancelBolus; - /** * 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 @@ -128,7 +145,6 @@ public class ComboPlugin extends PumpPluginBase implements Pump, Constraints { * direction - so that adding more complexity yields little benefit. */ private volatile boolean pumpHistoryChanged = false; - /** * 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 @@ -136,8 +152,11 @@ public class ComboPlugin extends PumpPluginBase implements Pump, Constraints { * after bolus delivery. Newest record is the first one. */ private volatile List recentBoluses = new ArrayList<>(0); - private PumpEnactResult OPERATION_NOT_SUPPORTED; + // Constraints interface + private long lowSuspendOnlyLoopEnforcedUntil = 0; + private long violationWarningRaisedForBolusAt = 0; + private boolean validBasalRateProfileSelectedOnPump = true; @Inject 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 */ @@ -850,10 +846,6 @@ public class ComboPlugin extends PumpPluginBase implements Pump, Constraints { return 0; } - private interface CommandExecution { - CommandResult execute(); - } - /** * Runs a command, sets an activity if provided, retries if requested and updates fields * concerned with last connection. @@ -980,7 +972,6 @@ public class ComboPlugin extends PumpPluginBase implements Pump, Constraints { return null; } - private void checkBasalRate(PumpState state) { if (!pump.initialized) { // no cached profile to compare against @@ -1386,22 +1377,17 @@ public class ComboPlugin extends PumpPluginBase implements Pump, Constraints { return result; } - // Constraints interface - private long lowSuspendOnlyLoopEnforcedUntil = 0; - private long violationWarningRaisedForBolusAt = 0; - private boolean validBasalRateProfileSelectedOnPump = true; - @NonNull @Override public Constraint isLoopInvocationAllowed(@NonNull Constraint value) { 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; } @NonNull @Override public Constraint applyMaxIOBConstraints(@NonNull Constraint maxIob) { 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; } @@ -1409,4 +1395,8 @@ public class ComboPlugin extends PumpPluginBase implements Pump, Constraints { public boolean canHandleDST() { return false; } + + private interface CommandExecution { + CommandResult execute(); + } } diff --git a/pump/combo/src/test/java/info/nightscout/pump/combo/ComboPluginTest.kt b/pump/combo/src/test/java/info/nightscout/pump/combo/ComboPluginTest.kt index 1d238e0cb4..dee5d1eb5b 100644 --- a/pump/combo/src/test/java/info/nightscout/pump/combo/ComboPluginTest.kt +++ b/pump/combo/src/test/java/info/nightscout/pump/combo/ComboPluginTest.kt @@ -3,7 +3,7 @@ package info.nightscout.pump.combo import android.content.Context import dagger.android.AndroidInjector 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.profile.ProfileFunction 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.pump.combo.ruffyscripter.RuffyScripter import info.nightscout.pump.combo.ruffyscripter.history.Bolus -import info.nightscout.rx.bus.RxBus import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.utils.DateUtil @@ -37,6 +36,9 @@ class ComboPluginTest : TestBase() { private val injector = HasAndroidInjector { AndroidInjector { + if (it is ConstraintObject<*>) { + it.aapsLogger = aapsLogger + } if (it is PumpEnactResult) { it.context = context } @@ -49,16 +51,15 @@ class ComboPluginTest : TestBase() { fun prepareMocks() { `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") - 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 fun invalidBasalRateOnComboPumpShouldLimitLoopInvocation() { comboPlugin.setPluginEnabled(PluginType.PUMP, true) comboPlugin.setValidBasalRateProfileSelectedOnPump(false) - var c = Constraint(true) - c = comboPlugin.isLoopInvocationAllowed(c) - Assertions.assertEquals("Combo: No valid basal rate read from pump", c.getReasons(aapsLogger)) + val c = comboPlugin.isLoopInvocationAllowed(ConstraintObject(true, injector)) + Assertions.assertEquals("Combo: No valid basal rate read from pump", c.getReasons()) Assertions.assertEquals(false, c.value()) comboPlugin.setPluginEnabled(PluginType.PUMP, false) } diff --git a/pump/combov2/build.gradle b/pump/combov2/build.gradle index fd35c11a7e..902108af6a 100644 --- a/pump/combov2/build.gradle +++ b/pump/combov2/build.gradle @@ -13,6 +13,7 @@ apply from: "${project.rootDir}/core/main/jacoco_global.gradle" dependencies { implementation project(':core:libraries') implementation project(':core:interfaces') + implementation project(':core:main') implementation project(':core:ui') implementation project(':core:utils') implementation(project(":pump:combov2:comboctl")) diff --git a/pump/combov2/src/main/kotlin/info/nightscout/pump/combov2/ComboV2Plugin.kt b/pump/combov2/src/main/kotlin/info/nightscout/pump/combov2/ComboV2Plugin.kt index 4cfac85c8e..b4029a24fd 100644 --- a/pump/combov2/src/main/kotlin/info/nightscout/pump/combov2/ComboV2Plugin.kt +++ b/pump/combov2/src/main/kotlin/info/nightscout/pump/combov2/ComboV2Plugin.kt @@ -25,12 +25,14 @@ import info.nightscout.comboctl.parser.AlertScreenContent import info.nightscout.comboctl.parser.AlertScreenException import info.nightscout.comboctl.parser.BatteryState import info.nightscout.comboctl.parser.ReservoirState +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.core.ui.dialogs.OKDialog import info.nightscout.core.ui.toast.ToastUtils import info.nightscout.interfaces.AndroidPermission import info.nightscout.interfaces.Config 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.plugin.PluginDescription import info.nightscout.interfaces.plugin.PluginType @@ -101,14 +103,14 @@ import info.nightscout.comboctl.main.PumpManager as ComboCtlPumpManager internal const val PUMP_ERROR_TIMEOUT_INTERVAL_MSECS = 1000L * 60 * 5 @Singleton -class ComboV2Plugin @Inject constructor ( +class ComboV2Plugin @Inject constructor( injector: HasAndroidInjector, aapsLogger: AAPSLogger, rh: ResourceHelper, commandQueue: CommandQueue, private val context: Context, private val rxBus: RxBus, - private val constraintChecker: Constraints, + private val constraintChecker: ConstraintsChecker, private val sp: SP, private val pumpSync: PumpSync, private val dateUtil: DateUtil, @@ -132,7 +134,7 @@ class ComboV2Plugin @Inject constructor ( commandQueue ), Pump, - Constraints { + PluginConstraints { // Coroutine scope and the associated job. All coroutines // 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(). // In setNewBasalProfile(), this value is changed. private var activeBasalProfile: BasalProfile? = null + // This is used for checking that the correct basal profile is // active in the Combo. If not, loop invocation is disallowed. // 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 ***/ sealed class DriverState(@Suppress("unused") val label: String) { + // 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 // is currently paired. In onStart() the driver state // changes from NotInitialized to this. - object Disconnected : DriverState("disconnected") + data object Disconnected : DriverState("disconnected") + // Driver is currently connecting to the pump. isBusy() // will return true in this state. - object Connecting : DriverState("connecting") + data object Connecting : DriverState("connecting") + // Driver is running checks on the pump, like verifying // that the basal rate is OK, checking for any bolus // and TBR activity that AAPS doesn't know about etc. // isBusy() will return true in this state. - object CheckingPump : DriverState("checkingPump") + data object CheckingPump : DriverState("checkingPump") + // 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 // cannot currently execute commands. This state is // special in that it technically persists even after @@ -252,11 +261,12 @@ class ComboV2Plugin @Inject constructor ( // the pump is currently suspended or not. Use // isSuspended() instead. See the pumpIsSuspended // documentation for details. - object Suspended : DriverState("suspended") + data object Suspended : DriverState("suspended") + // Driver is currently executing a command. // isBusy() will return true in this state. class ExecutingCommand(val description: ComboCtlPump.CommandDescription) : DriverState("executingCommand") - object Error : DriverState("error") + data object Error : DriverState("error") } private val driverStateFlow = _driverStateFlow.asStateFlow() @@ -264,7 +274,9 @@ class ComboV2Plugin @Inject constructor ( // Used by ComboV2PairingActivity to launch its own // custom activities that have a result. var customDiscoveryActivityStartCallback: ((intent: Intent) -> Unit)? - set(value) { bluetoothInterface?.customDiscoveryActivityStartCallback = value } + set(value) { + bluetoothInterface?.customDiscoveryActivityStartCallback = value + } get() = bluetoothInterface?.customDiscoveryActivityStartCallback init { @@ -494,6 +506,7 @@ class ComboV2Plugin @Inject constructor ( // returning true then causes problems with AAPS' KeepAlive mechanism. DriverState.CheckingPump, is DriverState.ExecutingCommand -> true + else -> false } @@ -509,6 +522,7 @@ class ComboV2Plugin @Inject constructor ( DriverState.Ready, DriverState.Suspended, is DriverState.ExecutingCommand -> true + else -> false } @@ -516,7 +530,8 @@ class ComboV2Plugin @Inject constructor ( when (driverStateFlow.value) { DriverState.Connecting, DriverState.CheckingPump -> true - else -> false + + else -> false } // There is no corresponding indicator for this @@ -554,7 +569,8 @@ class ComboV2Plugin @Inject constructor ( ) return } - else -> Unit + + else -> Unit } if (!isPaired()) { @@ -575,6 +591,7 @@ class ComboV2Plugin @Inject constructor ( unpairDueToPumpDataError() return } + else -> address } @@ -608,13 +625,13 @@ class ComboV2Plugin @Inject constructor ( // the rxBus too early, potentially causing a situation where the connect() // call isn't fully done yet, but the queue gets that event and thinks that // it can try to reconnect now. - ComboCtlPump.State.Disconnected -> return@onEach - ComboCtlPump.State.Connecting -> DriverState.Connecting - ComboCtlPump.State.CheckingPump -> DriverState.CheckingPump - ComboCtlPump.State.ReadyForCommands -> DriverState.Ready + ComboCtlPump.State.Disconnected -> return@onEach + ComboCtlPump.State.Connecting -> DriverState.Connecting + ComboCtlPump.State.CheckingPump -> DriverState.CheckingPump + ComboCtlPump.State.ReadyForCommands -> DriverState.Ready is ComboCtlPump.State.ExecutingCommand -> DriverState.ExecutingCommand(pumpState.description) - ComboCtlPump.State.Suspended -> DriverState.Suspended - is ComboCtlPump.State.Error -> DriverState.Error + ComboCtlPump.State.Suspended -> DriverState.Suspended + is ComboCtlPump.State.Error -> DriverState.Error } setDriverState(driverState) } @@ -686,7 +703,8 @@ class ComboV2Plugin @Inject constructor ( pumpIsSuspended = when (it.stateFlow.value) { ComboCtlPump.State.Suspended, is ComboCtlPump.State.Error -> true - else -> false + + else -> false } aapsLogger.debug(LTag.PUMP, "Pump is suspended: $pumpIsSuspended") @@ -970,8 +988,8 @@ class ComboV2Plugin @Inject constructor ( pumpStatus?.batteryState?.let { newState -> val newLevel = when (newState) { - BatteryState.NO_BATTERY -> 5 - BatteryState.LOW_BATTERY -> 25 + BatteryState.NO_BATTERY -> 5 + BatteryState.LOW_BATTERY -> 25 BatteryState.FULL_BATTERY -> 100 } @@ -996,7 +1014,7 @@ class ComboV2Plugin @Inject constructor ( override fun deliverTreatment(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult { val oldInsulinAmount = detailedBolusInfo.insulin detailedBolusInfo.insulin = constraintChecker - .applyBolusConstraints(Constraint(detailedBolusInfo.insulin)) + .applyBolusConstraints(ConstraintObject(detailedBolusInfo.insulin, injector)) .value() aapsLogger.debug( LTag.PUMP, @@ -1015,8 +1033,8 @@ class ComboV2Plugin @Inject constructor ( val requestedBolusAmount = detailedBolusInfo.insulin.iuToCctlBolus() val bolusReason = when (detailedBolusInfo.bolusType) { - DetailedBolusInfo.BolusType.NORMAL -> ComboCtlPump.StandardBolusReason.NORMAL - DetailedBolusInfo.BolusType.SMB -> ComboCtlPump.StandardBolusReason.SUPERBOLUS + DetailedBolusInfo.BolusType.NORMAL -> ComboCtlPump.StandardBolusReason.NORMAL + DetailedBolusInfo.BolusType.SMB -> ComboCtlPump.StandardBolusReason.SUPERBOLUS DetailedBolusInfo.BolusType.PRIMING -> ComboCtlPump.StandardBolusReason.PRIMING_INFUSION_SET } @@ -1055,13 +1073,15 @@ class ComboV2Plugin @Inject constructor ( bolusingEvent.status = rh.gs(info.nightscout.core.ui.R.string.bolus_delivering, detailedBolusInfo.insulin) rxBus.send(bolusingEvent) } - BasicProgressStage.Finished -> { + + BasicProgressStage.Finished -> { val bolusingEvent = EventOverviewBolusProgress bolusingEvent.percent = (progressReport.overallProgress * 100.0).toInt() bolusingEvent.status = "Bolus finished, performing post-bolus checks" rxBus.send(bolusingEvent) } - else -> Unit + + else -> Unit } } } @@ -1190,10 +1210,11 @@ class ComboV2Plugin @Inject constructor ( aapsLogger.debug(LTag.PUMP, "Calculated percentage of $percentage% out of absolute rate $absoluteRate; rounded to: $roundedPercentage%; limited to: $limitedPercentage%") val cctlTbrType = when (tbrType) { - PumpSync.TemporaryBasalType.NORMAL -> ComboCtlTbr.Type.NORMAL + PumpSync.TemporaryBasalType.NORMAL -> ComboCtlTbr.Type.NORMAL PumpSync.TemporaryBasalType.EMULATED_PUMP_SUSPEND -> ComboCtlTbr.Type.EMULATED_COMBO_STOP - PumpSync.TemporaryBasalType.SUPERBOLUS -> ComboCtlTbr.Type.SUPERBOLUS - PumpSync.TemporaryBasalType.PUMP_SUSPEND -> { + PumpSync.TemporaryBasalType.SUPERBOLUS -> ComboCtlTbr.Type.SUPERBOLUS + + PumpSync.TemporaryBasalType.PUMP_SUSPEND -> { aapsLogger.error( LTag.PUMP, "PUMP_SUSPEND TBR type produced by AAPS for the TBR initiation even though this is supposed to only be produced by pump drivers" @@ -1221,10 +1242,11 @@ class ComboV2Plugin @Inject constructor ( aapsLogger.debug(LTag.PUMP, "Got percentage of $percent%; rounded to: $roundedPercentage%; limited to: $limitedPercentage%") val cctlTbrType = when (tbrType) { - PumpSync.TemporaryBasalType.NORMAL -> ComboCtlTbr.Type.NORMAL + PumpSync.TemporaryBasalType.NORMAL -> ComboCtlTbr.Type.NORMAL PumpSync.TemporaryBasalType.EMULATED_PUMP_SUSPEND -> ComboCtlTbr.Type.EMULATED_COMBO_STOP - PumpSync.TemporaryBasalType.SUPERBOLUS -> ComboCtlTbr.Type.SUPERBOLUS - PumpSync.TemporaryBasalType.PUMP_SUSPEND -> { + PumpSync.TemporaryBasalType.SUPERBOLUS -> ComboCtlTbr.Type.SUPERBOLUS + + PumpSync.TemporaryBasalType.PUMP_SUSPEND -> { aapsLogger.error( LTag.PUMP, "PUMP_SUSPEND TBR type produced by AAPS for the TBR initiation even though this is supposed to only be produced by pump drivers" @@ -1277,10 +1299,13 @@ class ComboV2Plugin @Inject constructor ( val tbrComment = when (acquiredPump.setTbr(percentage, durationInMinutes, tbrType, force100Percent)) { ComboCtlPump.SetTbrOutcome.SET_NORMAL_TBR -> rh.gs(R.string.combov2_setting_tbr_succeeded) + ComboCtlPump.SetTbrOutcome.SET_EMULATED_100_TBR -> rh.gs(R.string.combov2_set_emulated_100_tbr) + ComboCtlPump.SetTbrOutcome.LETTING_EMULATED_100_TBR_FINISH -> rh.gs(R.string.combov2_letting_emulated_100_tbr_finish) + ComboCtlPump.SetTbrOutcome.IGNORED_REDUNDANT_100_TBR -> rh.gs(R.string.combov2_ignoring_redundant_100_tbr) } @@ -1381,7 +1406,7 @@ class ComboV2Plugin @Inject constructor ( } ?: aapsLogger.info( LTag.PUMP, "Cannot include reservoir level in JSON status " + - "since no such level is currently known" + "since no such level is currently known" ) put("extended", JSONObject().apply { put("Version", version) @@ -1401,15 +1426,17 @@ class ComboV2Plugin @Inject constructor ( aapsLogger.info( LTag.PUMP, "Cannot include base basal rate in JSON status " + - "since no basal profile is currently active" + "since no basal profile is currently active" ) put("ActiveProfile", profileName) when (val alert = lastComboAlert) { is AlertScreenContent.Warning -> put("WarningCode", alert.code) - is AlertScreenContent.Error -> + + is AlertScreenContent.Error -> put("ErrorCode", alert.code) - else -> Unit + + else -> Unit } }) } @@ -1448,8 +1475,8 @@ class ComboV2Plugin @Inject constructor ( val alertCodeString = when (val alert = lastComboAlert) { is AlertScreenContent.Warning -> "W${alert.code}" - is AlertScreenContent.Error -> "E${alert.code}" - else -> null + is AlertScreenContent.Error -> "E${alert.code}" + else -> null } if (alertCodeString != null) lines += rh.gs(R.string.combov2_short_status_alert, alertCodeString) @@ -1476,8 +1503,8 @@ class ComboV2Plugin @Inject constructor ( it.availableUnitsInReservoir ) val batteryStateDesc = when (it.batteryState) { - BatteryState.NO_BATTERY -> rh.gs(R.string.combov2_short_status_battery_state_empty) - BatteryState.LOW_BATTERY -> rh.gs(R.string.combov2_short_status_battery_state_low) + BatteryState.NO_BATTERY -> rh.gs(R.string.combov2_short_status_battery_state_empty) + BatteryState.LOW_BATTERY -> rh.gs(R.string.combov2_short_status_battery_state_low) BatteryState.FULL_BATTERY -> rh.gs(R.string.combov2_short_status_battery_state_full) } lines += rh.gs( @@ -1562,9 +1589,9 @@ class ComboV2Plugin @Inject constructor ( val reason = when (timeChangeType) { TimeChangeType.TimezoneChanged -> rh.gs(R.string.combov2_timezone_changed) - TimeChangeType.TimeChanged -> rh.gs(R.string.combov2_datetime_changed) - TimeChangeType.DSTStarted -> rh.gs(R.string.combov2_dst_started) - TimeChangeType.DSTEnded -> rh.gs(R.string.combov2_dst_ended) + TimeChangeType.TimeChanged -> rh.gs(R.string.combov2_datetime_changed) + TimeChangeType.DSTStarted -> rh.gs(R.string.combov2_dst_started) + TimeChangeType.DSTEnded -> rh.gs(R.string.combov2_dst_ended) } // Updating pump status implicitly also updates the pump's local datetime, // which is what we want after the system datetime/timezone/DST changed. @@ -1594,12 +1621,7 @@ class ComboV2Plugin @Inject constructor ( ) if (!isAllowed) { - value.set( - aapsLogger, - false, - rh.gs(R.string.combov2_incorrect_active_basal_profile, lastActiveBasalProfileNumber), - this - ) + value.set(false, rh.gs(R.string.combov2_incorrect_active_basal_profile, lastActiveBasalProfileNumber), this) } } else { aapsLogger.info( @@ -1753,7 +1775,6 @@ class ComboV2Plugin @Inject constructor ( // the PumpManager onPumpUnpaired callback. } - /*** User interface flows ***/ // "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 // a basal rate factor, reading the current pump datetime etc. data class CurrentActivityInfo(val description: String, val overallProgress: Double) + private fun noCurrentActivity() = CurrentActivityInfo("", 0.0) private var _currentActivityUIFlow = MutableStateFlow(noCurrentActivity()) val currentActivityUIFlow = _currentActivityUIFlow.asStateFlow() @@ -1799,6 +1821,7 @@ class ComboV2Plugin @Inject constructor ( val batteryStateUIFlow = _batteryStateUIFlow.asStateFlow() data class ReservoirLevel(val state: ReservoirState, val availableUnits: Int) + private var _reservoirLevelUIFlow = MutableStateFlow(null) val reservoirLevelUIFlow = _reservoirLevelUIFlow.asStateFlow() @@ -1830,7 +1853,6 @@ class ComboV2Plugin @Inject constructor ( private var _displayFrameUIFlow = MutableSharedFlow(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST) val displayFrameUIFlow = _displayFrameUIFlow.asSharedFlow() - /*** Misc private functions ***/ private fun setupUiFlows(acquiredPump: ComboCtlPump) { @@ -1845,6 +1867,7 @@ class ComboV2Plugin @Inject constructor ( R.string.combov2_establishing_bt_connection, progStage.currentAttemptNr ) + BasicProgressStage.PerformingConnectionHandshake -> rh.gs(R.string.combov2_pairing_performing_handshake) else -> "" } @@ -1860,10 +1883,12 @@ class ComboV2Plugin @Inject constructor ( val description = when (progressReport.stage) { RTCommandProgressStage.SettingDateTimeHour, RTCommandProgressStage.SettingDateTimeMinute -> rh.gs(R.string.combov2_setting_current_pump_time) + RTCommandProgressStage.SettingDateTimeYear, RTCommandProgressStage.SettingDateTimeMonth, - RTCommandProgressStage.SettingDateTimeDay -> rh.gs(R.string.combov2_setting_current_pump_date) - else -> "" + RTCommandProgressStage.SettingDateTimeDay -> rh.gs(R.string.combov2_setting_current_pump_date) + + else -> "" } _currentActivityUIFlow.value = CurrentActivityInfo( description, @@ -1877,7 +1902,8 @@ class ComboV2Plugin @Inject constructor ( val description = when (val stage = progressReport.stage) { is RTCommandProgressStage.GettingBasalProfile -> rh.gs(R.string.combov2_getting_basal_profile, stage.numSetFactors) - else -> "" + + else -> "" } _currentActivityUIFlow.value = CurrentActivityInfo( description, @@ -1891,7 +1917,8 @@ class ComboV2Plugin @Inject constructor ( val description = when (val stage = progressReport.stage) { is RTCommandProgressStage.SettingBasalProfile -> rh.gs(R.string.combov2_setting_basal_profile, stage.numSetFactors) - else -> "" + + else -> "" } _currentActivityUIFlow.value = CurrentActivityInfo( description, @@ -1906,10 +1933,11 @@ class ComboV2Plugin @Inject constructor ( is RTCommandProgressStage.DeliveringBolus -> rh.gs( R.string.combov2_delivering_bolus, - stage.deliveredImmediateAmount .cctlBolusToIU(), + stage.deliveredImmediateAmount.cctlBolusToIU(), stage.totalImmediateAmount.cctlBolusToIU() ) - else -> "" + + else -> "" } _currentActivityUIFlow.value = CurrentActivityInfo( description, @@ -1981,7 +2009,7 @@ class ComboV2Plugin @Inject constructor ( aapsLogger.debug(LTag.PUMP, "Handling pump event $event") when (event) { - is ComboCtlPump.Event.BatteryLow -> { + is ComboCtlPump.Event.BatteryLow -> { uiInteraction.addNotification( Notification.COMBO_PUMP_ALARM, text = rh.gs(R.string.combov2_battery_low_warning), @@ -1989,7 +2017,7 @@ class ComboV2Plugin @Inject constructor ( ) } - is ComboCtlPump.Event.ReservoirLow -> { + is ComboCtlPump.Event.ReservoirLow -> { uiInteraction.addNotification( Notification.COMBO_PUMP_ALARM, text = rh.gs(R.string.combov2_reservoir_low_warning), @@ -1997,7 +2025,7 @@ class ComboV2Plugin @Inject constructor ( ) } - is ComboCtlPump.Event.QuickBolusInfused -> { + is ComboCtlPump.Event.QuickBolusInfused -> { pumpSync.syncBolusWithPumpId( event.timestamp.toEpochMilliseconds(), event.bolusAmount.cctlBolusToIU(), @@ -2010,8 +2038,8 @@ class ComboV2Plugin @Inject constructor ( is ComboCtlPump.Event.StandardBolusInfused -> { val bolusType = when (event.standardBolusReason) { - ComboCtlPump.StandardBolusReason.NORMAL -> DetailedBolusInfo.BolusType.NORMAL - ComboCtlPump.StandardBolusReason.SUPERBOLUS -> DetailedBolusInfo.BolusType.SMB + ComboCtlPump.StandardBolusReason.NORMAL -> DetailedBolusInfo.BolusType.NORMAL + ComboCtlPump.StandardBolusReason.SUPERBOLUS -> DetailedBolusInfo.BolusType.SMB ComboCtlPump.StandardBolusReason.PRIMING_INFUSION_SET -> DetailedBolusInfo.BolusType.PRIMING } pumpSync.syncBolusWithPumpId( @@ -2036,7 +2064,7 @@ class ComboV2Plugin @Inject constructor ( ) } - is ComboCtlPump.Event.ExtendedBolusEnded -> { + is ComboCtlPump.Event.ExtendedBolusEnded -> { pumpSync.syncStopExtendedBolusWithPumpId( event.timestamp.toEpochMilliseconds(), event.bolusId, @@ -2045,15 +2073,15 @@ class ComboV2Plugin @Inject constructor ( ) } - is ComboCtlPump.Event.TbrStarted -> { + is ComboCtlPump.Event.TbrStarted -> { aapsLogger.debug(LTag.PUMP, "Pump reports TBR started; expected state according to AAPS: ${pumpSync.expectedPumpState()}") val tbrStartTimestampInMs = event.tbr.timestamp.toEpochMilliseconds() val tbrType = when (event.tbr.type) { - ComboCtlTbr.Type.NORMAL -> PumpSync.TemporaryBasalType.NORMAL + ComboCtlTbr.Type.NORMAL -> PumpSync.TemporaryBasalType.NORMAL ComboCtlTbr.Type.EMULATED_100_PERCENT -> PumpSync.TemporaryBasalType.NORMAL - ComboCtlTbr.Type.SUPERBOLUS -> PumpSync.TemporaryBasalType.SUPERBOLUS - ComboCtlTbr.Type.EMULATED_COMBO_STOP -> PumpSync.TemporaryBasalType.EMULATED_PUMP_SUSPEND - ComboCtlTbr.Type.COMBO_STOPPED -> PumpSync.TemporaryBasalType.PUMP_SUSPEND + ComboCtlTbr.Type.SUPERBOLUS -> PumpSync.TemporaryBasalType.SUPERBOLUS + ComboCtlTbr.Type.EMULATED_COMBO_STOP -> PumpSync.TemporaryBasalType.EMULATED_PUMP_SUSPEND + ComboCtlTbr.Type.COMBO_STOPPED -> PumpSync.TemporaryBasalType.PUMP_SUSPEND } pumpSync.syncTemporaryBasalWithPumpId( timestamp = tbrStartTimestampInMs, @@ -2067,7 +2095,7 @@ class ComboV2Plugin @Inject constructor ( ) } - is ComboCtlPump.Event.TbrEnded -> { + is ComboCtlPump.Event.TbrEnded -> { aapsLogger.debug(LTag.PUMP, "Pump reports TBR ended; expected state according to AAPS: ${pumpSync.expectedPumpState()}") val tbrEndTimestampInMs = event.timestampWhenTbrEnded.toEpochMilliseconds() pumpSync.syncStopTemporaryBasalWithPumpId( @@ -2078,7 +2106,7 @@ class ComboV2Plugin @Inject constructor ( ) } - is ComboCtlPump.Event.UnknownTbrDetected -> { + is ComboCtlPump.Event.UnknownTbrDetected -> { // Inform about this unknown TBR that was observed (and automatically aborted). val remainingDurationString = String.format( "%02d:%02d", @@ -2096,7 +2124,7 @@ class ComboV2Plugin @Inject constructor ( ) } - else -> Unit + else -> Unit } } @@ -2229,9 +2257,11 @@ class ComboV2Plugin @Inject constructor ( when (driverStateUIFlow.value) { DriverState.Error, DriverState.Suspended -> false - else -> true + + else -> true } } + else -> true } if (updateUIState) { @@ -2264,10 +2294,12 @@ class ComboV2Plugin @Inject constructor ( if (oldState != DriverState.Suspended) rxBus.send(EventPumpStatusChanged(EventPumpStatusChanged.Status.CONNECTED)) } + DriverState.Suspended -> { if (oldState != DriverState.Ready) rxBus.send(EventPumpStatusChanged(EventPumpStatusChanged.Status.CONNECTED)) } + else -> Unit } } @@ -2336,8 +2368,8 @@ class ComboV2Plugin @Inject constructor ( when (alert) { is AlertScreenContent.Warning -> { val desc = when (alert.code) { - 4 -> rh.gs(R.string.combov2_warning_4) - 10 -> rh.gs(R.string.combov2_warning_10) + 4 -> rh.gs(R.string.combov2_warning_4) + 10 -> rh.gs(R.string.combov2_warning_10) else -> "" } @@ -2345,18 +2377,18 @@ class ComboV2Plugin @Inject constructor ( if (desc.isEmpty()) "" else ": $desc" } - is AlertScreenContent.Error -> { + is AlertScreenContent.Error -> { val desc = when (alert.code) { - 1 -> rh.gs(R.string.combov2_error_1) - 2 -> rh.gs(R.string.combov2_error_2) - 4 -> rh.gs(R.string.combov2_error_4) - 5 -> rh.gs(R.string.combov2_error_5) - 6 -> rh.gs(R.string.combov2_error_6) - 7 -> rh.gs(R.string.combov2_error_7) - 8 -> rh.gs(R.string.combov2_error_8) - 9 -> rh.gs(R.string.combov2_error_9) - 10 -> rh.gs(R.string.combov2_error_10) - 11 -> rh.gs(R.string.combov2_error_11) + 1 -> rh.gs(R.string.combov2_error_1) + 2 -> rh.gs(R.string.combov2_error_2) + 4 -> rh.gs(R.string.combov2_error_4) + 5 -> rh.gs(R.string.combov2_error_5) + 6 -> rh.gs(R.string.combov2_error_6) + 7 -> rh.gs(R.string.combov2_error_7) + 8 -> rh.gs(R.string.combov2_error_8) + 9 -> rh.gs(R.string.combov2_error_9) + 10 -> rh.gs(R.string.combov2_error_10) + 11 -> rh.gs(R.string.combov2_error_11) else -> "" } @@ -2364,7 +2396,7 @@ class ComboV2Plugin @Inject constructor ( if (desc.isEmpty()) "" else ": $desc" } - else -> rh.gs(R.string.combov2_unrecognized_alert) + else -> rh.gs(R.string.combov2_unrecognized_alert) } private fun notifyAboutComboAlert(alert: AlertScreenContent) { @@ -2411,6 +2443,7 @@ class ComboV2Plugin @Inject constructor ( when (driverStateFlow.value) { DriverState.NotInitialized, DriverState.Disconnected -> true - else -> false + + else -> false } } diff --git a/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/DanaRKoreanPlugin.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/DanaRKoreanPlugin.kt index b2f3b92da9..f6936bc825 100644 --- a/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/DanaRKoreanPlugin.kt +++ b/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/DanaRKoreanPlugin.kt @@ -10,9 +10,9 @@ import info.nightscout.androidaps.danaRKorean.services.DanaRKoreanExecutionServi import info.nightscout.androidaps.danar.AbstractDanaRPlugin import info.nightscout.androidaps.danar.R import info.nightscout.annotations.OpenForTesting +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.core.utils.fabric.FabricPrivacy -import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.profile.Profile import info.nightscout.interfaces.pump.DetailedBolusInfo @@ -51,7 +51,7 @@ class DanaRKoreanPlugin @Inject constructor( rxBus: RxBus, private val context: Context, rh: ResourceHelper, - constraintChecker: Constraints, + constraintChecker: ConstraintsChecker, activePlugin: ActivePlugin, sp: SP, commandQueue: CommandQueue, @@ -147,7 +147,7 @@ class DanaRKoreanPlugin @Inject constructor( } 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) return if (detailedBolusInfo.insulin > 0) { 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 { // Recheck pump status if older than 30 min //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 val doLowTemp = absoluteRateAfterConstraint < baseBasalRate || absoluteRateAfterConstraint < 0.10 val doHighTemp = absoluteRateAfterConstraint > baseBasalRate && !useExtendedBoluses @@ -266,7 +266,7 @@ class DanaRKoreanPlugin @Inject constructor( val durationInHalfHours = max(durationInMinutes / 30, 1) // We keep current basal running so need to sub current basal 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 extendedRateToSet = Round.roundTo(extendedRateToSet, pumpDescription.extendedBolusStep * 2) // *2 because of half hours diff --git a/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/services/DanaRKoreanExecutionService.java b/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/services/DanaRKoreanExecutionService.java index efe68dac24..062262cf4e 100644 --- a/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/services/DanaRKoreanExecutionService.java +++ b/pump/danar/src/main/java/info/nightscout/androidaps/danaRKorean/services/DanaRKoreanExecutionService.java @@ -34,7 +34,7 @@ import info.nightscout.androidaps.danar.comm.MsgStatusBolusExtended; import info.nightscout.androidaps.danar.comm.MsgStatusTempBasal; import info.nightscout.androidaps.danar.services.AbstractDanaRExecutionService; 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.profile.Profile; import info.nightscout.interfaces.profile.ProfileFunction; @@ -62,7 +62,7 @@ public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService { @Inject AAPSLogger aapsLogger; @Inject RxBus rxBus; @Inject ResourceHelper rh; - @Inject Constraints constraintChecker; + @Inject ConstraintsChecker constraintChecker; @Inject DanaPump danaPump; @Inject DanaRPlugin danaRPlugin; @Inject DanaRKoreanPlugin danaRKoreanPlugin; @@ -83,12 +83,6 @@ public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService { mBinder = new LocalBinder(); } - public class LocalBinder extends Binder { - public DanaRKoreanExecutionService getServiceInstance() { - return DanaRKoreanExecutionService.this; - } - } - @SuppressLint("MissingPermission") public void connect() { if (mConnectionInProgress) return; @@ -330,4 +324,10 @@ public class DanaRKoreanExecutionService extends AbstractDanaRExecutionService { return null; } + public class LocalBinder extends Binder { + public DanaRKoreanExecutionService getServiceInstance() { + return DanaRKoreanExecutionService.this; + } + } + } diff --git a/pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/DanaRv2Plugin.java b/pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/DanaRv2Plugin.java index 7c35ab543e..77b6cc0aa7 100644 --- a/pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/DanaRv2Plugin.java +++ b/pump/danar/src/main/java/info/nightscout/androidaps/danaRv2/DanaRv2Plugin.java @@ -16,9 +16,9 @@ import info.nightscout.androidaps.danaRv2.services.DanaRv2ExecutionService; import info.nightscout.androidaps.danar.AbstractDanaRPlugin; import info.nightscout.androidaps.danar.R; import info.nightscout.annotations.OpenForTesting; +import info.nightscout.core.constraints.ConstraintObject; import info.nightscout.core.utils.fabric.FabricPrivacy; -import info.nightscout.interfaces.constraints.Constraint; -import info.nightscout.interfaces.constraints.Constraints; +import info.nightscout.interfaces.constraints.ConstraintsChecker; import info.nightscout.interfaces.plugin.ActivePlugin; import info.nightscout.interfaces.profile.Profile; import info.nightscout.interfaces.pump.DetailedBolusInfo; @@ -53,6 +53,19 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { private final DetailedBolusInfoStorage detailedBolusInfoStorage; private final TemporaryBasalStorage temporaryBasalStorage; 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 public DanaRv2Plugin( @@ -62,7 +75,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { RxBus rxBus, Context context, ResourceHelper rh, - Constraints constraintChecker, + ConstraintsChecker constraintChecker, ActivePlugin activePlugin, SP sp, CommandQueue commandQueue, @@ -111,20 +124,6 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { 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 @NonNull @Override @@ -160,7 +159,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { // Pump interface @NonNull @Override 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) { // v2 stores end time for bolus, we need to adjust time // default delivery speed is 12 sec/U @@ -225,7 +224,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { 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; 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) { DanaPump pump = danaPump; 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) { result.isTempCancel(false).enacted(false).success(false).comment(info.nightscout.core.ui.R.string.invalid_input); aapsLogger.error("setTempBasalPercent: Invalid input"); @@ -352,7 +351,7 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin { @NonNull @Override public PumpEnactResult setExtendedBolus(double insulin, int durationInMinutes) { DanaPump pump = danaPump; - insulin = constraintChecker.applyExtendedBolusConstraints(new Constraint<>(insulin)).value(); + insulin = constraintChecker.applyExtendedBolusConstraints(new ConstraintObject<>(insulin, getInjector())).value(); // needs to be rounded int durationInHalfHours = Math.max(durationInMinutes / 30, 1); insulin = Round.INSTANCE.roundTo(insulin, getPumpDescription().getExtendedBolusStep()); diff --git a/pump/danar/src/main/java/info/nightscout/androidaps/danar/AbstractDanaRPlugin.java b/pump/danar/src/main/java/info/nightscout/androidaps/danar/AbstractDanaRPlugin.java index f5d7c965d4..1304e70ca5 100644 --- a/pump/danar/src/main/java/info/nightscout/androidaps/danar/AbstractDanaRPlugin.java +++ b/pump/danar/src/main/java/info/nightscout/androidaps/danar/AbstractDanaRPlugin.java @@ -7,8 +7,10 @@ import org.json.JSONObject; import dagger.android.HasAndroidInjector; import info.nightscout.androidaps.danar.services.AbstractDanaRExecutionService; +import info.nightscout.core.constraints.ConstraintObject; 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.plugin.ActivePlugin; import info.nightscout.interfaces.plugin.OwnDatabasePlugin; @@ -46,7 +48,7 @@ import io.reactivex.rxjava3.disposables.CompositeDisposable; * 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 CompositeDisposable disposable = new CompositeDisposable(); @@ -55,7 +57,7 @@ public abstract class AbstractDanaRPlugin extends PumpPluginBase implements Pump protected PumpDescription pumpDescription = new PumpDescription(); protected DanaPump danaPump; - protected Constraints constraintChecker; + protected ConstraintsChecker constraintChecker; protected RxBus rxBus; protected ActivePlugin activePlugin; protected SP sp; @@ -65,11 +67,12 @@ public abstract class AbstractDanaRPlugin extends PumpPluginBase implements Pump protected UiInteraction uiInteraction; protected DanaHistoryDatabase danaHistoryDatabase; protected DecimalFormatter decimalFormatter; + protected AbstractDanaRPlugin( HasAndroidInjector injector, DanaPump danaPump, ResourceHelper rh, - Constraints constraintChecker, + ConstraintsChecker constraintChecker, AAPSLogger aapsLogger, AapsSchedulers aapsSchedulers, CommandQueue commandQueue, @@ -223,7 +226,7 @@ public abstract class AbstractDanaRPlugin extends PumpPluginBase implements Pump @NonNull @Override public PumpEnactResult setTempBasalPercent(int percent, int durationInMinutes, @NonNull Profile profile, boolean enforceNew, @NonNull PumpSync.TemporaryBasalType tbrType) { 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) { result.isTempCancel(false).enacted(false).success(false).comment(info.nightscout.core.ui.R.string.invalid_input); getAapsLogger().error("setTempBasalPercent: Invalid input"); @@ -270,7 +273,7 @@ public abstract class AbstractDanaRPlugin extends PumpPluginBase implements Pump @NonNull @Override 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 int durationInHalfHours = Math.max(durationInMinutes / 30, 1); insulin = Round.INSTANCE.roundTo(insulin, getPumpDescription().getExtendedBolusStep()); @@ -462,21 +465,21 @@ public abstract class AbstractDanaRPlugin extends PumpPluginBase implements Pump @NonNull @Override public Constraint applyBasalConstraints(Constraint 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; } @NonNull @Override public Constraint applyBasalPercentConstraints(Constraint 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.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.setIfGreater(0, getRh().gs(info.nightscout.core.ui.R.string.limitingpercentrate, 0, getRh().gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), 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; } @NonNull @Override public Constraint applyBolusConstraints(Constraint 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; } diff --git a/pump/danar/src/main/java/info/nightscout/androidaps/danar/DanaRPlugin.java b/pump/danar/src/main/java/info/nightscout/androidaps/danar/DanaRPlugin.java index ce102e2d25..ff4d9873be 100644 --- a/pump/danar/src/main/java/info/nightscout/androidaps/danar/DanaRPlugin.java +++ b/pump/danar/src/main/java/info/nightscout/androidaps/danar/DanaRPlugin.java @@ -14,9 +14,9 @@ import javax.inject.Singleton; import dagger.android.HasAndroidInjector; import info.nightscout.androidaps.danar.services.DanaRExecutionService; import info.nightscout.annotations.OpenForTesting; +import info.nightscout.core.constraints.ConstraintObject; import info.nightscout.core.utils.fabric.FabricPrivacy; -import info.nightscout.interfaces.constraints.Constraint; -import info.nightscout.interfaces.constraints.Constraints; +import info.nightscout.interfaces.constraints.ConstraintsChecker; import info.nightscout.interfaces.plugin.ActivePlugin; import info.nightscout.interfaces.profile.Profile; import info.nightscout.interfaces.pump.DetailedBolusInfo; @@ -46,8 +46,20 @@ public class DanaRPlugin extends AbstractDanaRPlugin { private final AAPSLogger aapsLogger; private final Context context; private final ResourceHelper rh; - private final Constraints constraints; 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 public DanaRPlugin( @@ -57,7 +69,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin { RxBus rxBus, Context context, ResourceHelper rh, - Constraints constraints, + ConstraintsChecker constraintsChecker, ActivePlugin activePlugin, SP sp, CommandQueue commandQueue, @@ -69,11 +81,10 @@ public class DanaRPlugin extends AbstractDanaRPlugin { DanaHistoryDatabase danaHistoryDatabase, 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.context = context; this.rh = rh; - this.constraints = constraints; this.fabricPrivacy = fabricPrivacy; useExtendedBoluses = sp.getBoolean(info.nightscout.core.utils.R.string.key_danar_useextended, false); @@ -114,20 +125,6 @@ public class DanaRPlugin extends AbstractDanaRPlugin { 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 @NonNull @Override @@ -163,7 +160,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin { @NonNull @Override 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) { EventOverviewBolusProgress.Treatment t = new EventOverviewBolusProgress.Treatment(0, 0, detailedBolusInfo.getBolusType() == DetailedBolusInfo.BolusType.SMB, detailedBolusInfo.getId()); 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 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; final boolean doLowTemp = absoluteRate < getBaseBasalRate() || absoluteRate < 0.10d; @@ -289,7 +286,7 @@ public class DanaRPlugin extends AbstractDanaRPlugin { int durationInHalfHours = Math.max(durationInMinutes / 30, 1); // We keep current basal running so need to sub current basal 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 extendedRateToSet = Round.INSTANCE.roundTo(extendedRateToSet, pumpDescription.getExtendedBolusStep() * 2); // *2 because of half hours diff --git a/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MessageBase.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MessageBase.kt index a4e81c0bbf..785bc1c840 100644 --- a/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MessageBase.kt +++ b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MessageBase.kt @@ -7,7 +7,7 @@ import info.nightscout.androidaps.danar.DanaRPlugin import info.nightscout.androidaps.danar.comm.MessageOriginalNames.getName import info.nightscout.androidaps.utils.CRC.getCrc16 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.pump.DetailedBolusInfoStorage import info.nightscout.interfaces.pump.PumpSync @@ -48,7 +48,7 @@ open class MessageBase(injector: HasAndroidInjector) { @Inject lateinit var commandQueue: CommandQueue @Inject lateinit var detailedBolusInfoStorage: DetailedBolusInfoStorage @Inject lateinit var temporaryBasalStorage: TemporaryBasalStorage - @Inject lateinit var constraintChecker: Constraints + @Inject lateinit var constraintChecker: ConstraintsChecker @Inject lateinit var pumpSync: PumpSync @Inject lateinit var danaHistoryRecordDao: DanaHistoryRecordDao @Inject lateinit var uiInteraction: UiInteraction diff --git a/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusStart.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusStart.kt index d22424bed1..0049f5b93e 100644 --- a/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusStart.kt +++ b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusStart.kt @@ -1,10 +1,9 @@ package info.nightscout.androidaps.danar.comm import dagger.android.HasAndroidInjector -import info.nightscout.interfaces.constraints.Constraint +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.rx.logging.LTag - class MsgBolusStart( injector: HasAndroidInjector, private var amount: Double @@ -13,7 +12,7 @@ class MsgBolusStart( init { setCommand(0x0102) // HARDCODED LIMIT - amount = constraintChecker.applyBolusConstraints(Constraint(amount)).value() + amount = constraintChecker.applyBolusConstraints(ConstraintObject(amount, injector)).value() addParamInt((amount * 100).toInt()) aapsLogger.debug(LTag.PUMPBTCOMM, "Bolus start : $amount") } diff --git a/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusStartWithSpeed.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusStartWithSpeed.kt index caa86a6b6b..3a0c72d41a 100644 --- a/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusStartWithSpeed.kt +++ b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgBolusStartWithSpeed.kt @@ -1,10 +1,9 @@ package info.nightscout.androidaps.danar.comm import dagger.android.HasAndroidInjector -import info.nightscout.interfaces.constraints.Constraint +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.rx.logging.LTag - class MsgBolusStartWithSpeed( injector: HasAndroidInjector, private var amount: Double, @@ -14,7 +13,7 @@ class MsgBolusStartWithSpeed( init { setCommand(0x0104) // HARDCODED LIMIT - amount = constraintChecker.applyBolusConstraints(Constraint(amount)).value() + amount = constraintChecker.applyBolusConstraints(ConstraintObject(amount, injector)).value() addParamInt((amount * 100).toInt()) addParamByte(speed.toByte()) aapsLogger.debug(LTag.PUMPBTCOMM, "Bolus start : $amount speed: $speed") @@ -24,10 +23,10 @@ class MsgBolusStartWithSpeed( val errorCode = intFromBuff(bytes, 0, 1) if (errorCode != 2) { failed = true - aapsLogger.debug(LTag.PUMPBTCOMM, "Messsage response: $errorCode FAILED!!") + aapsLogger.debug(LTag.PUMPBTCOMM, "Message response: $errorCode FAILED!!") } else { failed = false - aapsLogger.debug(LTag.PUMPBTCOMM, "Messsage response: $errorCode OK") + aapsLogger.debug(LTag.PUMPBTCOMM, "Message response: $errorCode OK") } danaPump.bolusStartErrorCode = errorCode } diff --git a/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetExtendedBolusStart.kt b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetExtendedBolusStart.kt index 3bfc0a5aad..9c1f1ed0bc 100644 --- a/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetExtendedBolusStart.kt +++ b/pump/danar/src/main/java/info/nightscout/androidaps/danar/comm/MsgSetExtendedBolusStart.kt @@ -1,14 +1,13 @@ package info.nightscout.androidaps.danar.comm import dagger.android.HasAndroidInjector -import info.nightscout.interfaces.constraints.Constraint +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.rx.logging.LTag - class MsgSetExtendedBolusStart( injector: HasAndroidInjector, private var amount: Double, - private var halfhours: Byte + private var halfHours: Byte ) : MessageBase(injector) { @@ -16,12 +15,12 @@ class MsgSetExtendedBolusStart( setCommand(0x0407) aapsLogger.debug(LTag.PUMPBTCOMM, "New message") // HARDCODED LIMITS - if (halfhours < 1) halfhours = 1 - if (halfhours > 16) halfhours = 16 - amount = constraintChecker.applyBolusConstraints(Constraint(amount)).value() + if (halfHours < 1) halfHours = 1 + if (halfHours > 16) halfHours = 16 + amount = constraintChecker.applyBolusConstraints(ConstraintObject(amount, injector)).value() addParamInt((amount * 100).toInt()) - addParamByte(halfhours) - aapsLogger.debug(LTag.PUMPBTCOMM, "Set extended bolus start: " + (amount * 100).toInt() / 100.0 + "U halfhours: " + halfhours.toInt()) + addParamByte(halfHours) + aapsLogger.debug(LTag.PUMPBTCOMM, "Set extended bolus start: " + (amount * 100).toInt() / 100.0 + "U halfHours: " + halfHours.toInt()) } override fun handleMessage(bytes: ByteArray) { diff --git a/pump/danar/src/test/java/info/nightscout/pump/danaR/DanaRPluginTest.kt b/pump/danar/src/test/java/info/nightscout/pump/danaR/DanaRPluginTest.kt index 095d7a676e..9f3585447a 100644 --- a/pump/danar/src/test/java/info/nightscout/pump/danaR/DanaRPluginTest.kt +++ b/pump/danar/src/test/java/info/nightscout/pump/danaR/DanaRPluginTest.kt @@ -3,9 +3,8 @@ package info.nightscout.pump.danaR import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector import info.nightscout.androidaps.danar.DanaRPlugin -import info.nightscout.interfaces.Constants -import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.core.constraints.ConstraintObject +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.plugin.PluginType import info.nightscout.interfaces.profile.Instantiator import info.nightscout.interfaces.pump.PumpSync @@ -22,7 +21,7 @@ import org.mockito.Mockito.`when` class DanaRPluginTest : TestBaseWithProfile() { - @Mock lateinit var constraintChecker: Constraints + @Mock lateinit var constraintChecker: ConstraintsChecker @Mock lateinit var commandQueue: CommandQueue @Mock lateinit var pumpSync: PumpSync @Mock lateinit var instantiator: Instantiator @@ -34,7 +33,11 @@ class DanaRPluginTest : TestBaseWithProfile() { private lateinit var danaRPlugin: DanaRPlugin val injector = HasAndroidInjector { - AndroidInjector { } + AndroidInjector { + if (it is ConstraintObject<*>) { + it.aapsLogger = aapsLogger + } + } } @BeforeEach @@ -57,11 +60,11 @@ class DanaRPluginTest : TestBaseWithProfile() { danaRPlugin.setPluginEnabled(PluginType.PUMP, true) danaRPlugin.setPluginEnabled(PluginType.PUMP, true) danaPump.maxBasal = 0.8 - val c = Constraint(Constants.REALLYHIGHBASALRATE) + val c = ConstraintObject(Double.MAX_VALUE, injector) danaRPlugin.applyBasalConstraints(c, validProfile) 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.getMostLimitedReasons(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()) } @Test @Throws(Exception::class) @@ -69,10 +72,10 @@ class DanaRPluginTest : TestBaseWithProfile() { danaRPlugin.setPluginEnabled(PluginType.PUMP, true) danaRPlugin.setPluginEnabled(PluginType.PUMP, true) danaPump.maxBasal = 0.8 - val c = Constraint(Constants.REALLYHIGHPERCENTBASALRATE) + val c = ConstraintObject(Int.MAX_VALUE, injector) danaRPlugin.applyBasalPercentConstraints(c, validProfile) 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.getMostLimitedReasons(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()) } } \ No newline at end of file diff --git a/pump/danar/src/test/java/info/nightscout/pump/danaR/comm/DanaRTestBase.kt b/pump/danar/src/test/java/info/nightscout/pump/danaR/comm/DanaRTestBase.kt index 363ccba06c..6f294d210b 100644 --- a/pump/danar/src/test/java/info/nightscout/pump/danaR/comm/DanaRTestBase.kt +++ b/pump/danar/src/test/java/info/nightscout/pump/danaR/comm/DanaRTestBase.kt @@ -6,8 +6,9 @@ import info.nightscout.androidaps.danaRKorean.DanaRKoreanPlugin import info.nightscout.androidaps.danaRv2.DanaRv2Plugin import info.nightscout.androidaps.danar.DanaRPlugin import info.nightscout.androidaps.danar.comm.MessageBase +import info.nightscout.core.constraints.ConstraintObject 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.pump.DetailedBolusInfoStorage 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.pump.dana.DanaPump import info.nightscout.pump.dana.database.DanaHistoryRecordDao -import info.nightscout.rx.bus.RxBus import info.nightscout.sharedtests.TestBaseWithProfile import org.junit.jupiter.api.BeforeEach import org.mockito.ArgumentMatchers @@ -32,7 +32,7 @@ open class DanaRTestBase : TestBaseWithProfile() { @Mock lateinit var configBuilder: ConfigBuilder @Mock lateinit var commandQueue: CommandQueue @Mock lateinit var detailedBolusInfoStorage: DetailedBolusInfoStorage - @Mock lateinit var constraintChecker: Constraints + @Mock lateinit var constraintChecker: ConstraintsChecker @Mock lateinit var pumpSync: PumpSync @Mock lateinit var danaHistoryRecordDao: DanaHistoryRecordDao @Mock lateinit var instantiator: Instantiator @@ -50,6 +50,9 @@ open class DanaRTestBase : TestBaseWithProfile() { val injector = HasAndroidInjector { AndroidInjector { + if (it is ConstraintObject<*>) { + it.aapsLogger = aapsLogger + } if (it is MessageBase) { it.aapsLogger = aapsLogger it.dateUtil = dateUtil @@ -57,7 +60,7 @@ open class DanaRTestBase : TestBaseWithProfile() { it.danaRPlugin = danaRPlugin it.danaRKoreanPlugin = danaRKoreanPlugin it.danaRv2Plugin = danaRv2Plugin - it.rxBus = RxBus(aapsSchedulers, aapsLogger) + it.rxBus = rxBus it.rh = rh it.activePlugin = activePlugin it.configBuilder = configBuilder diff --git a/pump/danar/src/test/java/info/nightscout/pump/danaR/comm/MessageHashTableRTest.kt b/pump/danar/src/test/java/info/nightscout/pump/danaR/comm/MessageHashTableRTest.kt index 9f4c683f63..83ac7c65e1 100644 --- a/pump/danar/src/test/java/info/nightscout/pump/danaR/comm/MessageHashTableRTest.kt +++ b/pump/danar/src/test/java/info/nightscout/pump/danaR/comm/MessageHashTableRTest.kt @@ -1,7 +1,7 @@ package info.nightscout.pump.danaR.comm 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.Test import org.mockito.Mockito @@ -9,7 +9,7 @@ import org.mockito.Mockito class MessageHashTableRTest : DanaRTestBase() { @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 testMessage = messageHashTable.findMessage(0x41f2) Assertions.assertEquals("CMD_HISTORY_ALL", testMessage.messageName) diff --git a/pump/danar/src/test/java/info/nightscout/pump/danaR/comm/MsgBolusStartTest.kt b/pump/danar/src/test/java/info/nightscout/pump/danaR/comm/MsgBolusStartTest.kt index da974f3209..daa4a0fb5a 100644 --- a/pump/danar/src/test/java/info/nightscout/pump/danaR/comm/MsgBolusStartTest.kt +++ b/pump/danar/src/test/java/info/nightscout/pump/danaR/comm/MsgBolusStartTest.kt @@ -1,7 +1,7 @@ package info.nightscout.pump.danaR.comm 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.Test import org.mockito.Mockito.`when` @@ -9,7 +9,7 @@ import org.mockito.Mockito.`when` class MsgBolusStartTest : DanaRTestBase() { @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) // test message decoding diff --git a/pump/danar/src/test/java/info/nightscout/pump/danaR/comm/MsgBolusStartWithSpeedTest.kt b/pump/danar/src/test/java/info/nightscout/pump/danaR/comm/MsgBolusStartWithSpeedTest.kt index ff2313a4a5..0493dc8b1e 100644 --- a/pump/danar/src/test/java/info/nightscout/pump/danaR/comm/MsgBolusStartWithSpeedTest.kt +++ b/pump/danar/src/test/java/info/nightscout/pump/danaR/comm/MsgBolusStartWithSpeedTest.kt @@ -1,7 +1,7 @@ package info.nightscout.pump.danaR.comm 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.Test import org.mockito.Mockito @@ -9,7 +9,7 @@ import org.mockito.Mockito class MsgBolusStartWithSpeedTest : DanaRTestBase() { @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) // test message decoding diff --git a/pump/danar/src/test/java/info/nightscout/pump/danaR/comm/MsgSetExtendedBolusStartTest.kt b/pump/danar/src/test/java/info/nightscout/pump/danaR/comm/MsgSetExtendedBolusStartTest.kt index 2cea8ca437..d881bd911e 100644 --- a/pump/danar/src/test/java/info/nightscout/pump/danaR/comm/MsgSetExtendedBolusStartTest.kt +++ b/pump/danar/src/test/java/info/nightscout/pump/danaR/comm/MsgSetExtendedBolusStartTest.kt @@ -1,7 +1,7 @@ package info.nightscout.pump.danaR.comm 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.Test import org.mockito.Mockito.`when` @@ -9,7 +9,7 @@ import org.mockito.Mockito.`when` class MsgSetExtendedBolusStartTest : DanaRTestBase() { @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()) // test message decoding diff --git a/pump/danar/src/test/java/info/nightscout/pump/danaRKorean/DanaRKoreanPluginTest.kt b/pump/danar/src/test/java/info/nightscout/pump/danaRKorean/DanaRKoreanPluginTest.kt index 59c583263f..d843b7e67c 100644 --- a/pump/danar/src/test/java/info/nightscout/pump/danaRKorean/DanaRKoreanPluginTest.kt +++ b/pump/danar/src/test/java/info/nightscout/pump/danaRKorean/DanaRKoreanPluginTest.kt @@ -3,9 +3,8 @@ package info.nightscout.pump.danaRKorean import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector import info.nightscout.androidaps.danaRKorean.DanaRKoreanPlugin -import info.nightscout.interfaces.Constants -import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.core.constraints.ConstraintObject +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.plugin.PluginType import info.nightscout.interfaces.profile.Instantiator import info.nightscout.interfaces.pump.PumpSync @@ -22,7 +21,7 @@ import org.mockito.Mockito.`when` class DanaRKoreanPluginTest : TestBaseWithProfile() { - @Mock lateinit var constraintChecker: Constraints + @Mock lateinit var constraintChecker: ConstraintsChecker @Mock lateinit var commandQueue: CommandQueue @Mock lateinit var pumpSync: PumpSync @Mock lateinit var instantiator: Instantiator @@ -34,7 +33,11 @@ class DanaRKoreanPluginTest : TestBaseWithProfile() { private lateinit var danaRPlugin: DanaRKoreanPlugin val injector = HasAndroidInjector { - AndroidInjector { } + AndroidInjector { + if (it is ConstraintObject<*>) { + it.aapsLogger = aapsLogger + } + } } @BeforeEach @@ -57,11 +60,11 @@ class DanaRKoreanPluginTest : TestBaseWithProfile() { danaRPlugin.setPluginEnabled(PluginType.PUMP, true) danaRPlugin.setPluginEnabled(PluginType.PUMP, true) danaPump.maxBasal = 0.8 - val c = Constraint(Constants.REALLYHIGHBASALRATE) + val c = ConstraintObject(Double.MAX_VALUE, injector) danaRPlugin.applyBasalConstraints(c, validProfile) 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.getMostLimitedReasons(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()) } @Test @Throws(Exception::class) @@ -69,10 +72,10 @@ class DanaRKoreanPluginTest : TestBaseWithProfile() { danaRPlugin.setPluginEnabled(PluginType.PUMP, true) danaRPlugin.setPluginEnabled(PluginType.PUMP, true) danaPump.maxBasal = 0.8 - val c = Constraint(Constants.REALLYHIGHPERCENTBASALRATE) + val c = ConstraintObject(Int.MAX_VALUE, injector) danaRPlugin.applyBasalPercentConstraints(c, validProfile) 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.getMostLimitedReasons(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()) } } \ No newline at end of file diff --git a/pump/danar/src/test/java/info/nightscout/pump/danaRKorean/comm/MessageHashTableRKoreanTest.kt b/pump/danar/src/test/java/info/nightscout/pump/danaRKorean/comm/MessageHashTableRKoreanTest.kt index 79fca9b748..8b43ed6677 100644 --- a/pump/danar/src/test/java/info/nightscout/pump/danaRKorean/comm/MessageHashTableRKoreanTest.kt +++ b/pump/danar/src/test/java/info/nightscout/pump/danaRKorean/comm/MessageHashTableRKoreanTest.kt @@ -1,7 +1,7 @@ package info.nightscout.pump.danaRKorean.comm 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 org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test @@ -10,7 +10,7 @@ import org.mockito.Mockito class MessageHashTableRKoreanTest : DanaRTestBase() { @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 testMessage = messageHashTable.findMessage(0x41f2) Assertions.assertEquals("CMD_HISTORY_ALL", testMessage.messageName) diff --git a/pump/danar/src/test/java/info/nightscout/pump/danaRv2/DanaRv2PluginTest.kt b/pump/danar/src/test/java/info/nightscout/pump/danaRv2/DanaRv2PluginTest.kt index d19b855b65..a95b45eef0 100644 --- a/pump/danar/src/test/java/info/nightscout/pump/danaRv2/DanaRv2PluginTest.kt +++ b/pump/danar/src/test/java/info/nightscout/pump/danaRv2/DanaRv2PluginTest.kt @@ -3,9 +3,8 @@ package info.nightscout.pump.danaRv2 import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector import info.nightscout.androidaps.danaRv2.DanaRv2Plugin -import info.nightscout.interfaces.Constants -import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.core.constraints.ConstraintObject +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.plugin.PluginType import info.nightscout.interfaces.profile.Instantiator import info.nightscout.interfaces.pump.DetailedBolusInfoStorage @@ -24,7 +23,7 @@ import org.mockito.Mockito.`when` class DanaRv2PluginTest : TestBaseWithProfile() { - @Mock lateinit var constraintChecker: Constraints + @Mock lateinit var constraintChecker: ConstraintsChecker @Mock lateinit var commandQueue: CommandQueue @Mock lateinit var detailedBolusInfoStorage: DetailedBolusInfoStorage @Mock lateinit var temporaryBasalStorage: TemporaryBasalStorage @@ -38,7 +37,11 @@ class DanaRv2PluginTest : TestBaseWithProfile() { private lateinit var danaRv2Plugin: DanaRv2Plugin val injector = HasAndroidInjector { - AndroidInjector { } + AndroidInjector { + if (it is ConstraintObject<*>) { + it.aapsLogger = aapsLogger + } + } } @BeforeEach @@ -61,11 +64,11 @@ class DanaRv2PluginTest : TestBaseWithProfile() { danaRv2Plugin.setPluginEnabled(PluginType.PUMP, true) danaRv2Plugin.setPluginEnabled(PluginType.PUMP, true) danaPump.maxBasal = 0.8 - val c = Constraint(Constants.REALLYHIGHBASALRATE) + val c = ConstraintObject(Double.MAX_VALUE, injector) danaRv2Plugin.applyBasalConstraints(c, validProfile) 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.getMostLimitedReasons(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()) } @Test @@ -73,10 +76,10 @@ class DanaRv2PluginTest : TestBaseWithProfile() { danaRv2Plugin.setPluginEnabled(PluginType.PUMP, true) danaRv2Plugin.setPluginEnabled(PluginType.PUMP, true) danaPump.maxBasal = 0.8 - val c = Constraint(Constants.REALLYHIGHPERCENTBASALRATE) + val c = ConstraintObject(Int.MAX_VALUE, injector) danaRv2Plugin.applyBasalPercentConstraints(c, validProfile) 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.getMostLimitedReasons(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()) } } \ No newline at end of file diff --git a/pump/danar/src/test/java/info/nightscout/pump/danaRv2/comm/MessageHashTableRv2Test.kt b/pump/danar/src/test/java/info/nightscout/pump/danaRv2/comm/MessageHashTableRv2Test.kt index 178b1488fc..94bfe539a4 100644 --- a/pump/danar/src/test/java/info/nightscout/pump/danaRv2/comm/MessageHashTableRv2Test.kt +++ b/pump/danar/src/test/java/info/nightscout/pump/danaRv2/comm/MessageHashTableRv2Test.kt @@ -3,7 +3,7 @@ package info.nightscout.pump.danaRv2.comm import info.nightscout.androidaps.danaRv2.comm.MessageHashTableRv2 import info.nightscout.androidaps.danaRv2.comm.MsgStatusAPS_v2 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 org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test @@ -13,7 +13,7 @@ class MessageHashTableRv2Test : DanaRTestBase() { @Test fun runTest() { - `when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(Constraint(0.0)) + `when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(ConstraintObject(0.0, injector)) val messageHashTableRv2 = MessageHashTableRv2(injector) val forTesting: MessageBase = MsgStatusAPS_v2(injector) val testPacket: MessageBase = messageHashTableRv2.findMessage(forTesting.command) diff --git a/pump/danars/src/main/java/info/nightscout/pump/danars/DanaRSPlugin.kt b/pump/danars/src/main/java/info/nightscout/pump/danars/DanaRSPlugin.kt index 2374eb15ae..89ce1b2430 100644 --- a/pump/danars/src/main/java/info/nightscout/pump/danars/DanaRSPlugin.kt +++ b/pump/danars/src/main/java/info/nightscout/pump/danars/DanaRSPlugin.kt @@ -8,10 +8,12 @@ import android.os.IBinder import android.text.format.DateFormat import androidx.preference.Preference import dagger.android.HasAndroidInjector +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.core.ui.toast.ToastUtils import info.nightscout.core.utils.fabric.FabricPrivacy 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.plugin.OwnDatabasePlugin import info.nightscout.interfaces.plugin.PluginDescription @@ -68,7 +70,7 @@ class DanaRSPlugin @Inject constructor( private val rxBus: RxBus, private val context: Context, rh: ResourceHelper, - private val constraintChecker: Constraints, + private val constraintChecker: ConstraintsChecker, private val profileFunction: ProfileFunction, private val sp: SP, commandQueue: CommandQueue, @@ -92,7 +94,7 @@ class DanaRSPlugin @Inject constructor( .preferencesId(R.xml.pref_danars) .description(info.nightscout.pump.dana.R.string.description_pump_dana_rs), injector, aapsLogger, rh, commandQueue -), Pump, Dana, Constraints, OwnDatabasePlugin { +), Pump, Dana, PluginConstraints, OwnDatabasePlugin { private val disposable = CompositeDisposable() private var danaRSService: DanaRSService? = null @@ -202,18 +204,22 @@ class DanaRSPlugin @Inject constructor( // Constraints interface override fun applyBasalConstraints(absoluteRate: Constraint, profile: Profile): Constraint { - 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 } override fun applyBasalPercentConstraints(percentRate: Constraint, profile: Profile): Constraint { - 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.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.setIfGreater(0, rh.gs(info.nightscout.core.ui.R.string.limitingpercentrate, 0, rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), 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 } override fun applyBolusConstraints(insulin: Constraint): Constraint { - 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 } @@ -282,7 +288,7 @@ class DanaRSPlugin @Inject constructor( @Synchronized 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) { val preferencesSpeed = sp.getInt(info.nightscout.pump.dana.R.string.key_danars_bolusspeed, 0) var speed = 12 @@ -337,7 +343,7 @@ class DanaRSPlugin @Inject constructor( // This is called from APS @Synchronized 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 val doLowTemp = absoluteAfterConstrain < baseBasalRate val doHighTemp = absoluteAfterConstrain > baseBasalRate @@ -413,7 +419,7 @@ class DanaRSPlugin @Inject constructor( @Synchronized override fun setTempBasalPercent(percent: Int, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: PumpSync.TemporaryBasalType): PumpEnactResult { val result = PumpEnactResult(injector) - var percentAfterConstraint = constraintChecker.applyBasalPercentConstraints(Constraint(percent), profile).value() + var percentAfterConstraint = constraintChecker.applyBasalPercentConstraints(ConstraintObject(percent, injector), profile).value() if (percentAfterConstraint < 0) { result.isTempCancel = false result.enacted = false @@ -483,7 +489,7 @@ class DanaRSPlugin @Inject constructor( @Synchronized 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 val durationInHalfHours = max(durationInMinutes / 30, 1) insulinAfterConstraint = Round.roundTo(insulinAfterConstraint, pumpDescription.extendedBolusStep) diff --git a/pump/danars/src/main/java/info/nightscout/pump/danars/comm/DanaRSPacketBolusSetStepBolusStart.kt b/pump/danars/src/main/java/info/nightscout/pump/danars/comm/DanaRSPacketBolusSetStepBolusStart.kt index 07c2c171ec..7ded74eea2 100644 --- a/pump/danars/src/main/java/info/nightscout/pump/danars/comm/DanaRSPacketBolusSetStepBolusStart.kt +++ b/pump/danars/src/main/java/info/nightscout/pump/danars/comm/DanaRSPacketBolusSetStepBolusStart.kt @@ -2,8 +2,8 @@ package info.nightscout.pump.danars.comm import dagger.android.HasAndroidInjector import info.nightscout.androidaps.danars.encryption.BleEncryption -import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.core.constraints.ConstraintObject +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.pump.dana.DanaPump import info.nightscout.rx.logging.LTag import javax.inject.Inject @@ -15,13 +15,13 @@ class DanaRSPacketBolusSetStepBolusStart( ) : DanaRSPacket(injector) { @Inject lateinit var danaPump: DanaPump - @Inject lateinit var constraintChecker: Constraints + @Inject lateinit var constraintChecker: ConstraintsChecker init { opCode = BleEncryption.DANAR_PACKET__OPCODE_BOLUS__SET_STEP_BOLUS_START // Speed 0 => 12 sec/U, 1 => 30 sec/U, 2 => 60 sec/U // 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") } diff --git a/pump/danars/src/main/java/info/nightscout/pump/danars/services/DanaRSService.kt b/pump/danars/src/main/java/info/nightscout/pump/danars/services/DanaRSService.kt index a230a49c53..e2e2d8a869 100644 --- a/pump/danars/src/main/java/info/nightscout/pump/danars/services/DanaRSService.kt +++ b/pump/danars/src/main/java/info/nightscout/pump/danars/services/DanaRSService.kt @@ -10,7 +10,7 @@ import dagger.android.DaggerService import dagger.android.HasAndroidInjector import info.nightscout.core.utils.fabric.FabricPrivacy 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.plugin.ActivePlugin import info.nightscout.interfaces.profile.Profile @@ -103,7 +103,7 @@ class DanaRSService : DaggerService() { @Inject lateinit var danaRSPlugin: DanaRSPlugin @Inject lateinit var danaPump: DanaPump @Inject lateinit var activePlugin: ActivePlugin - @Inject lateinit var constraintChecker: Constraints + @Inject lateinit var constraintChecker: ConstraintsChecker @Inject lateinit var uiInteraction: UiInteraction @Inject lateinit var bleComm: BLEComm @Inject lateinit var fabricPrivacy: FabricPrivacy diff --git a/pump/danars/src/test/java/info/nightscout/pump/danars/DanaRSPluginTest.kt b/pump/danars/src/test/java/info/nightscout/pump/danars/DanaRSPluginTest.kt index 958f46f0b4..c2a9d6cc36 100644 --- a/pump/danars/src/test/java/info/nightscout/pump/danars/DanaRSPluginTest.kt +++ b/pump/danars/src/test/java/info/nightscout/pump/danars/DanaRSPluginTest.kt @@ -1,9 +1,8 @@ package info.nightscout.pump.danars import dagger.android.AndroidInjector -import info.nightscout.interfaces.Constants -import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.core.constraints.ConstraintObject +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.plugin.PluginType import info.nightscout.interfaces.pump.DetailedBolusInfoStorage import info.nightscout.interfaces.pump.PumpSync @@ -20,7 +19,7 @@ import org.mockito.Mockito @Suppress("SpellCheckingInspection") class DanaRSPluginTest : DanaRSTestBase() { - @Mock lateinit var constraintChecker: Constraints + @Mock lateinit var constraintChecker: ConstraintsChecker @Mock lateinit var commandQueue: CommandQueue @Mock lateinit var detailedBolusInfoStorage: DetailedBolusInfoStorage @Mock lateinit var temporaryBasalStorage: TemporaryBasalStorage @@ -34,11 +33,11 @@ class DanaRSPluginTest : DanaRSTestBase() { danaRSPlugin.setPluginEnabled(PluginType.PUMP, true) danaRSPlugin.setPluginEnabled(PluginType.PUMP, true) danaPump.maxBasal = 0.8 - val c = Constraint(Constants.REALLYHIGHBASALRATE) + val c = ConstraintObject(Double.MAX_VALUE, injector) danaRSPlugin.applyBasalConstraints(c, validProfile) Assertions.assertEquals(java.lang.Double.valueOf(0.8), c.value(), 0.0001) - Assertions.assertEquals("DanaRS: limitingbasalratio", c.getReasons(aapsLogger)) - Assertions.assertEquals("DanaRS: limitingbasalratio", c.getMostLimitedReasons(aapsLogger)) + Assertions.assertEquals("DanaRS: limitingbasalratio", c.getReasons()) + Assertions.assertEquals("DanaRS: limitingbasalratio", c.getMostLimitedReasons()) } @Test @@ -46,11 +45,11 @@ class DanaRSPluginTest : DanaRSTestBase() { danaRSPlugin.setPluginEnabled(PluginType.PUMP, true) danaRSPlugin.setPluginEnabled(PluginType.PUMP, true) danaPump.maxBasal = 0.8 - val c = Constraint(Constants.REALLYHIGHPERCENTBASALRATE) + val c = ConstraintObject(Int.MAX_VALUE, injector) danaRSPlugin.applyBasalPercentConstraints(c, validProfile) Assertions.assertEquals(200, c.value()) - Assertions.assertEquals("DanaRS: limitingpercentrate", c.getReasons(aapsLogger)) - Assertions.assertEquals("DanaRS: limitingpercentrate", c.getMostLimitedReasons(aapsLogger)) + Assertions.assertEquals("DanaRS: limitingpercentrate", c.getReasons()) + Assertions.assertEquals("DanaRS: limitingpercentrate", c.getMostLimitedReasons()) } @BeforeEach diff --git a/pump/danars/src/test/java/info/nightscout/pump/danars/DanaRSTestBase.kt b/pump/danars/src/test/java/info/nightscout/pump/danars/DanaRSTestBase.kt index e64101e1f1..7c56fb2d9c 100644 --- a/pump/danars/src/test/java/info/nightscout/pump/danars/DanaRSTestBase.kt +++ b/pump/danars/src/test/java/info/nightscout/pump/danars/DanaRSTestBase.kt @@ -1,5 +1,8 @@ package info.nightscout.pump.danars +import dagger.android.AndroidInjector +import dagger.android.HasAndroidInjector +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.interfaces.profile.Instantiator import info.nightscout.interfaces.ui.UiInteraction import info.nightscout.pump.dana.DanaPump @@ -17,6 +20,14 @@ open class DanaRSTestBase : TestBaseWithProfile() { lateinit var danaPump: DanaPump + val injector = HasAndroidInjector { + AndroidInjector { + if (it is ConstraintObject<*>) { + it.aapsLogger = aapsLogger + } + } + } + @BeforeEach fun prepare() { Mockito.`when`(rh.gs(ArgumentMatchers.anyInt())).thenReturn("AnyString") diff --git a/pump/danars/src/test/java/info/nightscout/pump/danars/comm/DanaRsMessageHashTableTest.kt b/pump/danars/src/test/java/info/nightscout/pump/danars/comm/DanaRsMessageHashTableTest.kt index 466890cfb9..97a189240c 100644 --- a/pump/danars/src/test/java/info/nightscout/pump/danars/comm/DanaRsMessageHashTableTest.kt +++ b/pump/danars/src/test/java/info/nightscout/pump/danars/comm/DanaRsMessageHashTableTest.kt @@ -3,8 +3,8 @@ package info.nightscout.pump.danars.comm import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector import info.nightscout.androidaps.danars.encryption.BleEncryption -import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.core.constraints.ConstraintObject +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.pump.dana.DanaPump import info.nightscout.pump.danars.DanaRSTestBase import org.junit.jupiter.api.Assertions @@ -14,7 +14,7 @@ import org.mockito.Mockito.`when` class DanaRsMessageHashTableTest : DanaRSTestBase() { - @Mock lateinit var constraintChecker: Constraints + @Mock lateinit var constraintChecker: ConstraintsChecker private val packetInjector = HasAndroidInjector { AndroidInjector { @@ -36,7 +36,7 @@ class DanaRsMessageHashTableTest : DanaRSTestBase() { @Test fun runTest() { - `when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(Constraint(0.0)) + `when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(ConstraintObject(0.0, injector)) val danaRSMessageHashTable = DanaRSMessageHashTable(packetInjector) val forTesting: DanaRSPacket = DanaRSPacketAPSSetEventHistory(packetInjector, DanaPump.HistoryEntry.CARBS.value, 0, 0, 0) diff --git a/pump/danars/src/test/java/info/nightscout/pump/danars/comm/DanaRsPacketBolusSetStepBolusStartTest.kt b/pump/danars/src/test/java/info/nightscout/pump/danars/comm/DanaRsPacketBolusSetStepBolusStartTest.kt index b142a13226..27a8dcd7cd 100644 --- a/pump/danars/src/test/java/info/nightscout/pump/danars/comm/DanaRsPacketBolusSetStepBolusStartTest.kt +++ b/pump/danars/src/test/java/info/nightscout/pump/danars/comm/DanaRsPacketBolusSetStepBolusStartTest.kt @@ -2,8 +2,8 @@ package info.nightscout.pump.danars.comm import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector -import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.core.constraints.ConstraintObject +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.pump.DetailedBolusInfoStorage import info.nightscout.interfaces.pump.PumpSync import info.nightscout.interfaces.pump.TemporaryBasalStorage @@ -18,7 +18,7 @@ import org.mockito.Mockito class DanaRsPacketBolusSetStepBolusStartTest : DanaRSTestBase() { - @Mock lateinit var constraintChecker: Constraints + @Mock lateinit var constraintChecker: ConstraintsChecker @Mock lateinit var commandQueue: CommandQueue @Mock lateinit var detailedBolusInfoStorage: DetailedBolusInfoStorage @Mock lateinit var temporaryBasalStorage: TemporaryBasalStorage @@ -75,6 +75,6 @@ class DanaRsPacketBolusSetStepBolusStartTest : DanaRSTestBase() { danaHistoryDatabase, decimalFormatter ) - Mockito.`when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(Constraint(0.0)) + Mockito.`when`(constraintChecker.applyBolusConstraints(anyObject())).thenReturn(ConstraintObject(0.0, injector)) } } \ No newline at end of file diff --git a/pump/danars/src/test/java/info/nightscout/pump/danars/comm/DanaRsPacketNotifyDeliveryRateDisplayTest.kt b/pump/danars/src/test/java/info/nightscout/pump/danars/comm/DanaRsPacketNotifyDeliveryRateDisplayTest.kt index dc0cdef0e8..08865517af 100644 --- a/pump/danars/src/test/java/info/nightscout/pump/danars/comm/DanaRsPacketNotifyDeliveryRateDisplayTest.kt +++ b/pump/danars/src/test/java/info/nightscout/pump/danars/comm/DanaRsPacketNotifyDeliveryRateDisplayTest.kt @@ -2,7 +2,7 @@ package info.nightscout.pump.danars.comm import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.pump.DetailedBolusInfoStorage import info.nightscout.interfaces.pump.PumpSync import info.nightscout.interfaces.pump.TemporaryBasalStorage @@ -20,7 +20,7 @@ import org.mockito.Mockito.`when` class DanaRsPacketNotifyDeliveryRateDisplayTest : DanaRSTestBase() { @Mock lateinit var danaHistoryDatabase: DanaHistoryDatabase - @Mock lateinit var constraintChecker: Constraints + @Mock lateinit var constraintChecker: ConstraintsChecker @Mock lateinit var commandQueue: CommandQueue @Mock lateinit var detailedBolusInfoStorage: DetailedBolusInfoStorage @Mock lateinit var temporaryBasalStorage: TemporaryBasalStorage diff --git a/pump/diaconn/src/main/java/info/nightscout/pump/diaconn/DiaconnG8Plugin.kt b/pump/diaconn/src/main/java/info/nightscout/pump/diaconn/DiaconnG8Plugin.kt index caf8c0f2c0..0ed3187bbb 100644 --- a/pump/diaconn/src/main/java/info/nightscout/pump/diaconn/DiaconnG8Plugin.kt +++ b/pump/diaconn/src/main/java/info/nightscout/pump/diaconn/DiaconnG8Plugin.kt @@ -9,10 +9,12 @@ import android.text.format.DateFormat import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import dagger.android.HasAndroidInjector +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.core.ui.toast.ToastUtils import info.nightscout.core.utils.fabric.FabricPrivacy 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.plugin.OwnDatabasePlugin import info.nightscout.interfaces.plugin.PluginDescription @@ -66,7 +68,7 @@ class DiaconnG8Plugin @Inject constructor( private val rxBus: RxBus, private val context: Context, rh: ResourceHelper, - private val constraintChecker: Constraints, + private val constraintChecker: ConstraintsChecker, private val profileFunction: ProfileFunction, private val sp: SP, commandQueue: CommandQueue, @@ -90,7 +92,7 @@ class DiaconnG8Plugin @Inject constructor( .preferencesId(R.xml.pref_diaconn) .description(R.string.description_pump_diaconn_g8), injector, aapsLogger, rh, commandQueue -), Pump, Diaconn, Constraints, OwnDatabasePlugin { +), Pump, Diaconn, PluginConstraints, OwnDatabasePlugin { private val disposable = CompositeDisposable() private var diaconnG8Service: DiaconnG8Service? = null @@ -185,18 +187,22 @@ class DiaconnG8Plugin @Inject constructor( // Constraints interface override fun applyBasalConstraints(absoluteRate: Constraint, profile: Profile): Constraint { - absoluteRate.setIfSmaller(aapsLogger, diaconnG8Pump.maxBasal, rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, diaconnG8Pump.maxBasal, rh.gs(info.nightscout.core.ui.R.string.pumplimit)), this) + absoluteRate.setIfSmaller(diaconnG8Pump.maxBasal, rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, diaconnG8Pump.maxBasal, rh.gs(info.nightscout.core.ui.R.string.pumplimit)), this) return absoluteRate } override fun applyBasalPercentConstraints(percentRate: Constraint, profile: Profile): Constraint { - 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.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.setIfGreater(0, rh.gs(info.nightscout.core.ui.R.string.limitingpercentrate, 0, rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), 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 } override fun applyBolusConstraints(insulin: Constraint): Constraint { - insulin.setIfSmaller(aapsLogger, diaconnG8Pump.maxBolus, rh.gs(info.nightscout.core.ui.R.string.limitingbolus, diaconnG8Pump.maxBolus, rh.gs(info.nightscout.core.ui.R.string.pumplimit)), this) + insulin.setIfSmaller(diaconnG8Pump.maxBolus, rh.gs(info.nightscout.core.ui.R.string.limitingbolus, diaconnG8Pump.maxBolus, rh.gs(info.nightscout.core.ui.R.string.pumplimit)), this) return insulin } @@ -265,7 +271,7 @@ class DiaconnG8Plugin @Inject constructor( @Synchronized 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) { val carbs = detailedBolusInfo.carbs detailedBolusInfo.carbs = 0.0 @@ -304,7 +310,7 @@ class DiaconnG8Plugin @Inject constructor( @Synchronized override fun setTempBasalAbsolute(absoluteRate: Double, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: PumpSync.TemporaryBasalType): PumpEnactResult { val result = PumpEnactResult(injector) - val absoluteAfterConstrain = constraintChecker.applyBasalConstraints(Constraint(absoluteRate), profile).value() + val absoluteAfterConstrain = constraintChecker.applyBasalConstraints(ConstraintObject(absoluteRate, injector), profile).value() val doTempOff = baseBasalRate - absoluteAfterConstrain == 0.0 val doLowTemp = absoluteAfterConstrain < baseBasalRate val doHighTemp = absoluteAfterConstrain > baseBasalRate @@ -391,7 +397,7 @@ class DiaconnG8Plugin @Inject constructor( @Synchronized 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 insulinAfterConstraint = Round.roundTo(insulinAfterConstraint, pumpDescription.extendedBolusStep) val result = PumpEnactResult(injector) diff --git a/pump/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicTestBase.kt b/pump/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicTestBase.kt index ced4a4bc8f..f58892816e 100644 --- a/pump/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicTestBase.kt +++ b/pump/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicTestBase.kt @@ -11,8 +11,6 @@ import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.pump.PumpSync import info.nightscout.pump.common.sync.PumpSyncStorage import info.nightscout.pump.core.utils.ByteUtil -import info.nightscout.rx.TestAapsSchedulers -import info.nightscout.rx.bus.RxBus import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.sharedPreferences.SP import info.nightscout.sharedtests.TestBase @@ -21,7 +19,6 @@ import org.mockito.Mock open class MedtronicTestBase : TestBase() { - var rxBus: RxBus = RxBus(TestAapsSchedulers(), aapsLogger) var byteUtil = ByteUtil() var rileyLinkUtil = RileyLinkUtil() diff --git a/pump/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicHistoryDataUTest.kt b/pump/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicHistoryDataUTest.kt index 434eb8e8df..dd77853710 100644 --- a/pump/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicHistoryDataUTest.kt +++ b/pump/medtronic/src/test/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/MedtronicHistoryDataUTest.kt @@ -14,8 +14,6 @@ import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil import info.nightscout.database.impl.serialisation.SealedClassHelper import info.nightscout.interfaces.ui.UiInteraction import info.nightscout.pump.core.utils.ByteUtil -import info.nightscout.rx.TestAapsSchedulers -import info.nightscout.rx.bus.RxBus import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.mockito.Mock @@ -37,8 +35,6 @@ import org.mockito.Mock @BeforeEach fun setup() { - rxBus = RxBus(TestAapsSchedulers(), aapsLogger) - medtronicPumpStatus = MedtronicPumpStatus(rh, sp, rxBus, rileyLinkUtil) medtronicUtil = MedtronicUtil(aapsLogger, rxBus, rileyLinkUtil, medtronicPumpStatus, uiInteraction) decoder = MedtronicPumpHistoryDecoder(aapsLogger, medtronicUtil, byteUtil) diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/MedtrumPlugin.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/MedtrumPlugin.kt index efcda22669..d4f41f9e74 100644 --- a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/MedtrumPlugin.kt +++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/MedtrumPlugin.kt @@ -12,12 +12,12 @@ import androidx.preference.EditTextPreference import androidx.preference.ListPreference import androidx.preference.PreferenceFragmentCompat import dagger.android.HasAndroidInjector +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.core.ui.dialogs.OKDialog import info.nightscout.core.ui.toast.ToastUtils import info.nightscout.core.utils.fabric.FabricPrivacy import info.nightscout.core.validators.ValidatingEditTextPreference -import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.notifications.Notification import info.nightscout.interfaces.plugin.PluginDescription import info.nightscout.interfaces.plugin.PluginType @@ -67,7 +67,7 @@ import kotlin.math.abs aapsLogger: AAPSLogger, rh: ResourceHelper, commandQueue: CommandQueue, - private val constraintChecker: Constraints, + private val constraintChecker: ConstraintsChecker, private val aapsSchedulers: AapsSchedulers, private val rxBus: RxBus, private val context: Context, @@ -348,7 +348,7 @@ import kotlin.math.abs override fun deliverTreatment(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult { aapsLogger.debug(LTag.PUMP, "deliverTreatment: " + detailedBolusInfo.insulin + "U") if (!isInitialized()) return PumpEnactResult(injector).success(false).enacted(false) - 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.0) { aapsLogger.debug(LTag.PUMP, "deliverTreatment: Delivering bolus: " + detailedBolusInfo.insulin + "U") val t = EventOverviewBolusProgress.Treatment(0.0, 0, detailedBolusInfo.bolusType == DetailedBolusInfo.BolusType.SMB, detailedBolusInfo.id) @@ -388,7 +388,7 @@ import kotlin.math.abs aapsLogger.info(LTag.PUMP, "setTempBasalAbsolute - absoluteRate: $absoluteRate, durationInMinutes: $durationInMinutes, enforceNew: $enforceNew") // round rate to pump rate - val pumpRate = constraintChecker.applyBasalConstraints(Constraint(absoluteRate), profile).value() + val pumpRate = constraintChecker.applyBasalConstraints(ConstraintObject(absoluteRate, injector), profile).value() temporaryBasalStorage.add(PumpSync.PumpState.TemporaryBasal(dateUtil.now(), T.mins(durationInMinutes.toLong()).msecs(), pumpRate, true, tbrType, 0L, 0L)) val connectionOK = medtrumService?.setTempBasal(pumpRate, durationInMinutes) ?: false return if (connectionOK diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/services/MedtrumService.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/services/MedtrumService.kt index a94d4dde69..b5165b47c4 100644 --- a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/services/MedtrumService.kt +++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/services/MedtrumService.kt @@ -9,7 +9,7 @@ import android.os.SystemClock import dagger.android.DaggerService import dagger.android.HasAndroidInjector import info.nightscout.core.utils.fabric.FabricPrivacy -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.notifications.Notification import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.profile.Profile @@ -86,7 +86,7 @@ class MedtrumService : DaggerService(), BLECommCallback { @Inject lateinit var medtrumPlugin: MedtrumPlugin @Inject lateinit var medtrumPump: MedtrumPump @Inject lateinit var activePlugin: ActivePlugin - @Inject lateinit var constraintChecker: Constraints + @Inject lateinit var constraintChecker: ConstraintsChecker @Inject lateinit var uiInteraction: UiInteraction @Inject lateinit var bleComm: BLEComm @Inject lateinit var fabricPrivacy: FabricPrivacy @@ -432,7 +432,7 @@ class MedtrumService : DaggerService(), BLECommCallback { connectionRetryCounter++ } else { communicationLost = true - aapsLogger.warn(LTag.PUMPCOMM, "Retry connection faled, communication stopped") + aapsLogger.warn(LTag.PUMPCOMM, "Retry connection failed, communication stopped") disconnect("Communication stopped") } } else { diff --git a/pump/omnipod-dash/build.gradle b/pump/omnipod-dash/build.gradle index 2021a42fa5..7057f8a12c 100644 --- a/pump/omnipod-dash/build.gradle +++ b/pump/omnipod-dash/build.gradle @@ -41,6 +41,7 @@ dependencies { api "androidx.room:room-rxjava3:$room_version" kapt "androidx.room:room-compiler:$room_version" + androidTestImplementation project(':app-wear-shared:shared-tests') testImplementation project(':app-wear-shared:shared-tests') testImplementation "commons-codec:commons-codec:$commonscodec_version" diff --git a/pump/omnipod-dash/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/DashHistoryTest.kt b/pump/omnipod-dash/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/DashHistoryTest.kt index 1dfda4ffc1..8c9ea1cd8f 100644 --- a/pump/omnipod-dash/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/DashHistoryTest.kt +++ b/pump/omnipod-dash/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/DashHistoryTest.kt @@ -10,7 +10,6 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.database.His import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.mapper.HistoryMapper import info.nightscout.sharedtests.AAPSLoggerTest import org.junit.Before -import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.Test import org.junit.runner.RunWith diff --git a/pump/omnipod-eros/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/ErosHistoryTest.kt b/pump/omnipod-eros/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/ErosHistoryTest.kt index c585f2552e..d8c0da7cae 100644 --- a/pump/omnipod-eros/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/ErosHistoryTest.kt +++ b/pump/omnipod-eros/src/androidTest/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/history/ErosHistoryTest.kt @@ -10,6 +10,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.eros.history.database.Ero import org.junit.Assert.assertNotNull import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test class ErosHistoryTest { diff --git a/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPluginTest.kt b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPluginTest.kt index 9b7bd7e5a3..a4dae6e21f 100644 --- a/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPluginTest.kt +++ b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPluginTest.kt @@ -14,10 +14,9 @@ import info.nightscout.interfaces.queue.CommandQueue import info.nightscout.interfaces.ui.UiInteraction import info.nightscout.interfaces.utils.DecimalFormatter import info.nightscout.pump.common.defs.TempBasalPair -import info.nightscout.rx.TestAapsSchedulers -import info.nightscout.rx.bus.RxBus import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.sharedtests.TestBase +import info.nightscout.sharedtests.rx.TestAapsSchedulers import org.joda.time.DateTimeZone import org.joda.time.tz.UTCProvider import org.junit.jupiter.api.Assertions @@ -41,7 +40,6 @@ class OmnipodErosPumpPluginTest : TestBase() { @Mock lateinit var erosHistoryDatabase: ErosHistoryDatabase private lateinit var decimalFormatter: DecimalFormatter - private var rxBusWrapper = RxBus(TestAapsSchedulers(), aapsLogger) @BeforeEach fun prepare() { `when`(rh.gs(ArgumentMatchers.anyInt(), ArgumentMatchers.anyLong())) @@ -54,7 +52,7 @@ class OmnipodErosPumpPluginTest : TestBase() { // mock all the things val plugin = OmnipodErosPumpPlugin( - injector, aapsLogger, TestAapsSchedulers(), rxBusWrapper, null, + injector, aapsLogger, TestAapsSchedulers(), rxBus, null, rh, null, null, aapsOmnipodErosManager, commandQueue, null, null, null, null, rileyLinkUtil, null, null, pumpSync, uiInteraction, erosHistoryDatabase, decimalFormatter diff --git a/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsErosPodStateManagerTest.kt b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsErosPodStateManagerTest.kt index 9d63fafec5..f798368d1c 100644 --- a/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsErosPodStateManagerTest.kt +++ b/pump/omnipod-eros/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/manager/AapsErosPodStateManagerTest.kt @@ -2,10 +2,8 @@ package info.nightscout.androidaps.plugins.pump.omnipod.eros.manager import info.nightscout.androidaps.plugins.pump.omnipod.eros.driver.definition.FirmwareVersion import info.nightscout.androidaps.plugins.pump.omnipod.eros.driver.definition.PodProgressStatus -import info.nightscout.shared.impl.rx.bus.RxBusImpl import info.nightscout.shared.sharedPreferences.SP import info.nightscout.sharedtests.TestBase -import info.nightscout.sharedtests.rx.TestAapsSchedulers import org.joda.time.DateTime import org.joda.time.DateTimeUtils import org.joda.time.DateTimeZone @@ -19,8 +17,6 @@ class AapsErosPodStateManagerTest : TestBase() { @Mock lateinit var sp: SP - private val rxBus = RxBusImpl(TestAapsSchedulers(), aapsLogger) - @Test fun times() { val timeZone = DateTimeZone.UTC DateTimeZone.setDefault(timeZone) diff --git a/pump/pump-common/src/main/java/info/nightscout/pump/common/PumpPluginAbstract.kt b/pump/pump-common/src/main/java/info/nightscout/pump/common/PumpPluginAbstract.kt index 3c5517200a..fbf9738856 100644 --- a/pump/pump-common/src/main/java/info/nightscout/pump/common/PumpPluginAbstract.kt +++ b/pump/pump-common/src/main/java/info/nightscout/pump/common/PumpPluginAbstract.kt @@ -8,7 +8,7 @@ import com.google.gson.Gson import com.google.gson.GsonBuilder import dagger.android.HasAndroidInjector import info.nightscout.core.utils.fabric.FabricPrivacy -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.interfaces.constraints.PluginConstraints import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.plugin.PluginDescription import info.nightscout.interfaces.profile.Profile @@ -63,7 +63,7 @@ abstract class PumpPluginAbstract protected constructor( var pumpSync: PumpSync, var pumpSyncStorage: PumpSyncStorage, var decimalFormatter: DecimalFormatter -) : PumpPluginBase(pluginDescription, injector, aapsLogger, rh, commandQueue), Pump, Constraints, PumpSyncEntriesCreator { +) : PumpPluginBase(pluginDescription, injector, aapsLogger, rh, commandQueue), Pump, PluginConstraints, PumpSyncEntriesCreator { protected val disposable = CompositeDisposable() diff --git a/pump/virtual/src/test/java/info/nightscout/pump/virtual/VirtualPumpPluginUTest.kt b/pump/virtual/src/test/java/info/nightscout/pump/virtual/VirtualPumpPluginUTest.kt index e9c2922e52..87722bf9b4 100644 --- a/pump/virtual/src/test/java/info/nightscout/pump/virtual/VirtualPumpPluginUTest.kt +++ b/pump/virtual/src/test/java/info/nightscout/pump/virtual/VirtualPumpPluginUTest.kt @@ -9,7 +9,6 @@ import info.nightscout.interfaces.profile.ProfileFunction import info.nightscout.interfaces.pump.PumpSync import info.nightscout.interfaces.pump.defs.PumpType import info.nightscout.interfaces.queue.CommandQueue -import info.nightscout.rx.bus.RxBus import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.utils.DateUtil @@ -22,7 +21,6 @@ import org.mockito.Mockito.`when` class VirtualPumpPluginUTest : TestBase() { - private val rxBus = RxBus(aapsSchedulers, aapsLogger) @Mock lateinit var fabricPrivacy: FabricPrivacy @Mock lateinit var rh: ResourceHelper @Mock lateinit var sp: SP diff --git a/ui/src/main/java/info/nightscout/ui/dialogs/CarbsDialog.kt b/ui/src/main/java/info/nightscout/ui/dialogs/CarbsDialog.kt index 927733e1e7..8095e08415 100644 --- a/ui/src/main/java/info/nightscout/ui/dialogs/CarbsDialog.kt +++ b/ui/src/main/java/info/nightscout/ui/dialogs/CarbsDialog.kt @@ -8,6 +8,8 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import com.google.common.base.Joiner +import dagger.android.HasAndroidInjector +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.core.ui.dialogs.OKDialog import info.nightscout.core.ui.toast.ToastUtils import info.nightscout.core.utils.HtmlHelper @@ -23,8 +25,7 @@ import info.nightscout.interfaces.Constants.CARBS_FAV2_DEFAULT import info.nightscout.interfaces.Constants.CARBS_FAV3_DEFAULT import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.automation.Automation -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.IobCobCalculator import info.nightscout.interfaces.logging.UserEntryLogger @@ -54,7 +55,7 @@ class CarbsDialog : DialogFragmentWithDate() { @Inject lateinit var ctx: Context @Inject lateinit var rh: ResourceHelper - @Inject lateinit var constraintChecker: Constraints + @Inject lateinit var constraintChecker: ConstraintsChecker @Inject lateinit var defaultValueHelper: DefaultValueHelper @Inject lateinit var profileUtil: ProfileUtil @Inject lateinit var iobCobCalculator: IobCobCalculator @@ -66,6 +67,7 @@ class CarbsDialog : DialogFragmentWithDate() { @Inject lateinit var protectionCheck: ProtectionCheck @Inject lateinit var uiInteraction: UiInteraction @Inject lateinit var decimalFormatter: DecimalFormatter + @Inject lateinit var injector: HasAndroidInjector private var queryingProtection = false private val disposable = CompositeDisposable() @@ -225,7 +227,7 @@ class CarbsDialog : DialogFragmentWithDate() { override fun submit(): Boolean { if (_binding == null) return false val carbs = binding.carbs.value.toInt() - val carbsAfterConstraints = constraintChecker.applyCarbsConstraints(Constraint(carbs)).value() + val carbsAfterConstraints = constraintChecker.applyCarbsConstraints(ConstraintObject(carbs, injector)).value() val units = profileUtil.units val activityTTDuration = defaultValueHelper.determineActivityTTDuration() val activityTT = defaultValueHelper.determineActivityTT() diff --git a/ui/src/main/java/info/nightscout/ui/dialogs/ExtendedBolusDialog.kt b/ui/src/main/java/info/nightscout/ui/dialogs/ExtendedBolusDialog.kt index 10f02b2f0f..49ecf11135 100644 --- a/ui/src/main/java/info/nightscout/ui/dialogs/ExtendedBolusDialog.kt +++ b/ui/src/main/java/info/nightscout/ui/dialogs/ExtendedBolusDialog.kt @@ -6,14 +6,15 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import com.google.common.base.Joiner +import dagger.android.HasAndroidInjector +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.core.ui.dialogs.OKDialog import info.nightscout.core.ui.toast.ToastUtils import info.nightscout.core.utils.HtmlHelper import info.nightscout.core.utils.extensions.formatColor import info.nightscout.database.entities.UserEntry import info.nightscout.database.entities.ValueWithUnit -import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.logging.UserEntryLogger import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.protection.ProtectionCheck @@ -34,12 +35,13 @@ class ExtendedBolusDialog : DialogFragmentWithDate() { @Inject lateinit var ctx: Context @Inject lateinit var rh: ResourceHelper - @Inject lateinit var constraintChecker: Constraints + @Inject lateinit var constraintChecker: ConstraintsChecker @Inject lateinit var commandQueue: CommandQueue @Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var uel: UserEntryLogger @Inject lateinit var protectionCheck: ProtectionCheck @Inject lateinit var uiInteraction: UiInteraction + @Inject lateinit var injector: HasAndroidInjector private var queryingProtection = false private var _binding: DialogExtendedbolusBinding? = null @@ -94,7 +96,7 @@ class ExtendedBolusDialog : DialogFragmentWithDate() { val insulin = SafeParse.stringToDouble(binding.insulin.text) val durationInMinutes = binding.duration.value.toInt() val actions: LinkedList = LinkedList() - val insulinAfterConstraint = constraintChecker.applyExtendedBolusConstraints(Constraint(insulin)).value() + val insulinAfterConstraint = constraintChecker.applyExtendedBolusConstraints(ConstraintObject(insulin, injector)).value() actions.add(rh.gs(info.nightscout.core.ui.R.string.format_insulin_units, insulinAfterConstraint)) actions.add(rh.gs(info.nightscout.core.ui.R.string.duration) + ": " + rh.gs(info.nightscout.core.ui.R.string.format_mins, durationInMinutes)) if (abs(insulinAfterConstraint - insulin) > 0.01) diff --git a/ui/src/main/java/info/nightscout/ui/dialogs/FillDialog.kt b/ui/src/main/java/info/nightscout/ui/dialogs/FillDialog.kt index 2b1084f47b..7f149d45d6 100644 --- a/ui/src/main/java/info/nightscout/ui/dialogs/FillDialog.kt +++ b/ui/src/main/java/info/nightscout/ui/dialogs/FillDialog.kt @@ -6,6 +6,8 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import com.google.common.base.Joiner +import dagger.android.HasAndroidInjector +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.core.ui.dialogs.OKDialog import info.nightscout.core.ui.toast.ToastUtils import info.nightscout.core.utils.HtmlHelper @@ -15,8 +17,7 @@ import info.nightscout.database.entities.UserEntry import info.nightscout.database.entities.ValueWithUnit import info.nightscout.database.impl.AppRepository import info.nightscout.database.impl.transactions.InsertIfNewByTimestampTherapyEventTransaction -import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.logging.UserEntryLogger import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.protection.ProtectionCheck @@ -38,7 +39,7 @@ import kotlin.math.abs class FillDialog : DialogFragmentWithDate() { - @Inject lateinit var constraintChecker: Constraints + @Inject lateinit var constraintChecker: ConstraintsChecker @Inject lateinit var rh: ResourceHelper @Inject lateinit var ctx: Context @Inject lateinit var commandQueue: CommandQueue @@ -48,6 +49,7 @@ class FillDialog : DialogFragmentWithDate() { @Inject lateinit var protectionCheck: ProtectionCheck @Inject lateinit var uiInteraction: UiInteraction @Inject lateinit var decimalFormatter: DecimalFormatter + @Inject lateinit var injector: HasAndroidInjector private var queryingProtection = false private val disposable = CompositeDisposable() @@ -116,7 +118,7 @@ class FillDialog : DialogFragmentWithDate() { val insulin = SafeParse.stringToDouble(binding.fillInsulinAmount.text) val actions: LinkedList = LinkedList() - val insulinAfterConstraints = constraintChecker.applyBolusConstraints(Constraint(insulin)).value() + val insulinAfterConstraints = constraintChecker.applyBolusConstraints(ConstraintObject(insulin, injector)).value() if (insulinAfterConstraints > 0) { actions.add(rh.gs(R.string.fill_warning)) actions.add("") diff --git a/ui/src/main/java/info/nightscout/ui/dialogs/InsulinDialog.kt b/ui/src/main/java/info/nightscout/ui/dialogs/InsulinDialog.kt index c741980f7c..9602f779c1 100644 --- a/ui/src/main/java/info/nightscout/ui/dialogs/InsulinDialog.kt +++ b/ui/src/main/java/info/nightscout/ui/dialogs/InsulinDialog.kt @@ -8,6 +8,8 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import com.google.common.base.Joiner +import dagger.android.HasAndroidInjector +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.core.ui.dialogs.OKDialog import info.nightscout.core.ui.toast.ToastUtils import info.nightscout.core.utils.HtmlHelper @@ -23,8 +25,7 @@ import info.nightscout.interfaces.Constants.INSULIN_PLUS2_DEFAULT import info.nightscout.interfaces.Constants.INSULIN_PLUS3_DEFAULT import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.automation.Automation -import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.db.PersistenceLayer import info.nightscout.interfaces.logging.UserEntryLogger import info.nightscout.interfaces.plugin.ActivePlugin @@ -56,7 +57,7 @@ import kotlin.math.max class InsulinDialog : DialogFragmentWithDate() { - @Inject lateinit var constraintChecker: Constraints + @Inject lateinit var constraintChecker: ConstraintsChecker @Inject lateinit var rh: ResourceHelper @Inject lateinit var defaultValueHelper: DefaultValueHelper @Inject lateinit var profileFunction: ProfileFunction @@ -72,6 +73,7 @@ class InsulinDialog : DialogFragmentWithDate() { @Inject lateinit var uiInteraction: UiInteraction @Inject lateinit var persistenceLayer: PersistenceLayer @Inject lateinit var decimalFormatter: DecimalFormatter + @Inject lateinit var injector: HasAndroidInjector private var queryingProtection = false private val disposable = CompositeDisposable() @@ -189,7 +191,7 @@ class InsulinDialog : DialogFragmentWithDate() { if (_binding == null) return false val pumpDescription = activePlugin.activePump.pumpDescription val insulin = SafeParse.stringToDouble(binding.amount.text) - val insulinAfterConstraints = constraintChecker.applyBolusConstraints(Constraint(insulin)).value() + val insulinAfterConstraints = constraintChecker.applyBolusConstraints(ConstraintObject(insulin, injector)).value() val actions: LinkedList = LinkedList() val units = profileFunction.getUnits() val unitLabel = if (units == GlucoseUnit.MMOL) rh.gs(info.nightscout.core.ui.R.string.mmol) else rh.gs(info.nightscout.core.ui.R.string.mgdl) diff --git a/ui/src/main/java/info/nightscout/ui/dialogs/LoopDialog.kt b/ui/src/main/java/info/nightscout/ui/dialogs/LoopDialog.kt index e668f6bee8..eb9ed9bbee 100644 --- a/ui/src/main/java/info/nightscout/ui/dialogs/LoopDialog.kt +++ b/ui/src/main/java/info/nightscout/ui/dialogs/LoopDialog.kt @@ -10,7 +10,9 @@ import android.view.ViewGroup import android.view.Window import android.view.WindowManager import androidx.fragment.app.FragmentManager +import dagger.android.HasAndroidInjector import dagger.android.support.DaggerDialogFragment +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.core.ui.dialogs.OKDialog import info.nightscout.core.ui.toast.ToastUtils import info.nightscout.core.utils.fabric.FabricPrivacy @@ -20,11 +22,10 @@ import info.nightscout.database.entities.ValueWithUnit import info.nightscout.database.impl.AppRepository import info.nightscout.database.impl.transactions.CancelCurrentOfflineEventIfAnyTransaction import info.nightscout.database.impl.transactions.InsertAndCancelCurrentOfflineEventTransaction -import info.nightscout.interfaces.ConfigBuilder import info.nightscout.interfaces.ApsMode +import info.nightscout.interfaces.ConfigBuilder import info.nightscout.interfaces.aps.Loop -import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.constraints.Objectives import info.nightscout.interfaces.logging.UserEntryLogger import info.nightscout.interfaces.plugin.ActivePlugin @@ -64,7 +65,7 @@ class LoopDialog : DaggerDialogFragment() { @Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var loop: Loop @Inject lateinit var activePlugin: ActivePlugin - @Inject lateinit var constraintChecker: Constraints + @Inject lateinit var constraintChecker: ConstraintsChecker @Inject lateinit var commandQueue: CommandQueue @Inject lateinit var configBuilder: ConfigBuilder @Inject lateinit var uel: UserEntryLogger @@ -72,6 +73,7 @@ class LoopDialog : DaggerDialogFragment() { @Inject lateinit var repository: AppRepository @Inject lateinit var protectionCheck: ProtectionCheck @Inject lateinit var uiInteraction: UiInteraction + @Inject lateinit var injector: HasAndroidInjector private var queryingProtection = false private var showOkCancel: Boolean = true @@ -152,16 +154,14 @@ class LoopDialog : DaggerDialogFragment() { disposable.clear() } - var task: Runnable? = null - @Synchronized fun updateGUI(from: String) { if (_binding == null) return aapsLogger.debug("UpdateGUI from $from") val pumpDescription: PumpDescription = activePlugin.activePump.pumpDescription - val closedLoopAllowed = constraintChecker.isClosedLoopAllowed(Constraint(true)) + val closedLoopAllowed = constraintChecker.isClosedLoopAllowed(ConstraintObject(true, injector)) val closedLoopAllowed2 = activePlugin.activeObjectives?.isAccomplished(Objectives.MAXIOB_OBJECTIVE) ?: false - val lgsEnabled = constraintChecker.isLgsAllowed(Constraint(true)) + val lgsEnabled = constraintChecker.isLgsAllowed(ConstraintObject(true, injector)) val apsMode = ApsMode.fromString(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)) val pump = activePlugin.activePump @@ -279,7 +279,7 @@ class LoopDialog : DaggerDialogFragment() { return true } - fun onClick(v: View): Boolean { + private fun onClick(v: View): Boolean { when (v.id) { R.id.overview_closeloop -> { uel.log(UserEntry.Action.CLOSED_LOOP_MODE, UserEntry.Sources.LoopDialog) diff --git a/ui/src/main/java/info/nightscout/ui/dialogs/TempBasalDialog.kt b/ui/src/main/java/info/nightscout/ui/dialogs/TempBasalDialog.kt index 730af01f57..4cf3cf85d8 100644 --- a/ui/src/main/java/info/nightscout/ui/dialogs/TempBasalDialog.kt +++ b/ui/src/main/java/info/nightscout/ui/dialogs/TempBasalDialog.kt @@ -6,14 +6,15 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import com.google.common.base.Joiner +import dagger.android.HasAndroidInjector +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.core.ui.dialogs.OKDialog import info.nightscout.core.ui.toast.ToastUtils import info.nightscout.core.utils.HtmlHelper import info.nightscout.core.utils.extensions.formatColor import info.nightscout.database.entities.UserEntry import info.nightscout.database.entities.ValueWithUnit -import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.logging.UserEntryLogger import info.nightscout.interfaces.plugin.ActivePlugin import info.nightscout.interfaces.profile.ProfileFunction @@ -35,7 +36,7 @@ import kotlin.math.abs class TempBasalDialog : DialogFragmentWithDate() { - @Inject lateinit var constraintChecker: Constraints + @Inject lateinit var constraintChecker: ConstraintsChecker @Inject lateinit var rh: ResourceHelper @Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var activePlugin: ActivePlugin @@ -44,6 +45,7 @@ class TempBasalDialog : DialogFragmentWithDate() { @Inject lateinit var uel: UserEntryLogger @Inject lateinit var protectionCheck: ProtectionCheck @Inject lateinit var uiInteraction: UiInteraction + @Inject lateinit var injector: HasAndroidInjector private var queryingProtection = false private var isPercentPump = true @@ -118,13 +120,13 @@ class TempBasalDialog : DialogFragmentWithDate() { val actions: LinkedList = LinkedList() if (isPercentPump) { val basalPercentInput = SafeParse.stringToInt(binding.basalPercentInput.text) - percent = constraintChecker.applyBasalPercentConstraints(Constraint(basalPercentInput), profile).value() + percent = constraintChecker.applyBasalPercentConstraints(ConstraintObject(basalPercentInput, injector), profile).value() actions.add(rh.gs(info.nightscout.core.ui.R.string.tempbasal_label) + ": $percent%") actions.add(rh.gs(info.nightscout.core.ui.R.string.duration) + ": " + rh.gs(info.nightscout.core.ui.R.string.format_mins, durationInMinutes)) if (percent != basalPercentInput) actions.add(rh.gs(info.nightscout.core.ui.R.string.constraint_applied)) } else { val basalAbsoluteInput = SafeParse.stringToDouble(binding.basalAbsoluteInput.text) - absolute = constraintChecker.applyBasalConstraints(Constraint(basalAbsoluteInput), profile).value() + absolute = constraintChecker.applyBasalConstraints(ConstraintObject(basalAbsoluteInput, injector), profile).value() actions.add(rh.gs(info.nightscout.core.ui.R.string.tempbasal_label) + ": " + rh.gs(info.nightscout.core.ui.R.string.pump_base_basal_rate, absolute)) actions.add(rh.gs(info.nightscout.core.ui.R.string.duration) + ": " + rh.gs(info.nightscout.core.ui.R.string.format_mins, durationInMinutes)) if (abs(absolute - basalAbsoluteInput) > 0.01) diff --git a/ui/src/main/java/info/nightscout/ui/dialogs/TempTargetDialog.kt b/ui/src/main/java/info/nightscout/ui/dialogs/TempTargetDialog.kt index 7e08d66765..8fe66ed052 100644 --- a/ui/src/main/java/info/nightscout/ui/dialogs/TempTargetDialog.kt +++ b/ui/src/main/java/info/nightscout/ui/dialogs/TempTargetDialog.kt @@ -20,7 +20,7 @@ import info.nightscout.database.impl.transactions.CancelCurrentTemporaryTargetIf import info.nightscout.database.impl.transactions.InsertAndCancelCurrentTemporaryTargetTransaction import info.nightscout.interfaces.Constants import info.nightscout.interfaces.GlucoseUnit -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.logging.UserEntryLogger import info.nightscout.interfaces.profile.DefaultValueHelper import info.nightscout.interfaces.profile.ProfileFunction @@ -39,7 +39,7 @@ import javax.inject.Inject class TempTargetDialog : DialogFragmentWithDate() { - @Inject lateinit var constraintChecker: Constraints + @Inject lateinit var constraintChecker: ConstraintsChecker @Inject lateinit var rh: ResourceHelper @Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var profileUtil: ProfileUtil diff --git a/ui/src/main/java/info/nightscout/ui/dialogs/TreatmentDialog.kt b/ui/src/main/java/info/nightscout/ui/dialogs/TreatmentDialog.kt index 25e2905bf4..02099655ce 100644 --- a/ui/src/main/java/info/nightscout/ui/dialogs/TreatmentDialog.kt +++ b/ui/src/main/java/info/nightscout/ui/dialogs/TreatmentDialog.kt @@ -8,6 +8,8 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import com.google.common.base.Joiner +import dagger.android.HasAndroidInjector +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.core.ui.dialogs.OKDialog import info.nightscout.core.ui.toast.ToastUtils import info.nightscout.core.utils.HtmlHelper @@ -16,8 +18,7 @@ import info.nightscout.database.entities.UserEntry import info.nightscout.database.entities.ValueWithUnit import info.nightscout.database.impl.AppRepository import info.nightscout.interfaces.Config -import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.db.PersistenceLayer import info.nightscout.interfaces.logging.UserEntryLogger import info.nightscout.interfaces.plugin.ActivePlugin @@ -32,7 +33,6 @@ import info.nightscout.shared.SafeParse import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.ui.R import info.nightscout.ui.databinding.DialogTreatmentBinding -import io.reactivex.rxjava3.disposables.CompositeDisposable import java.text.DecimalFormat import java.util.LinkedList import javax.inject.Inject @@ -40,7 +40,7 @@ import kotlin.math.abs class TreatmentDialog : DialogFragmentWithDate() { - @Inject lateinit var constraintChecker: Constraints + @Inject lateinit var constraintChecker: ConstraintsChecker @Inject lateinit var rh: ResourceHelper @Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var commandQueue: CommandQueue @@ -52,9 +52,9 @@ class TreatmentDialog : DialogFragmentWithDate() { @Inject lateinit var uiInteraction: UiInteraction @Inject lateinit var persistenceLayer: PersistenceLayer @Inject lateinit var decimalFormatter: DecimalFormatter + @Inject lateinit var injector: HasAndroidInjector private var queryingProtection = false - private val disposable = CompositeDisposable() private var _binding: DialogTreatmentBinding? = null // This property is only valid between onCreateView and onDestroyView. @@ -138,8 +138,8 @@ class TreatmentDialog : DialogFragmentWithDate() { val carbs = SafeParse.stringToInt(binding.carbs.text) val recordOnlyChecked = binding.recordOnly.isChecked val actions: LinkedList = LinkedList() - val insulinAfterConstraints = constraintChecker.applyBolusConstraints(Constraint(insulin)).value() - val carbsAfterConstraints = constraintChecker.applyCarbsConstraints(Constraint(carbs)).value() + val insulinAfterConstraints = constraintChecker.applyBolusConstraints(ConstraintObject(insulin, injector)).value() + val carbsAfterConstraints = constraintChecker.applyCarbsConstraints(ConstraintObject(carbs, injector)).value() if (insulinAfterConstraints > 0) { actions.add( diff --git a/ui/src/main/java/info/nightscout/ui/dialogs/WizardDialog.kt b/ui/src/main/java/info/nightscout/ui/dialogs/WizardDialog.kt index 690e6080a1..3b8dd042bf 100644 --- a/ui/src/main/java/info/nightscout/ui/dialogs/WizardDialog.kt +++ b/ui/src/main/java/info/nightscout/ui/dialogs/WizardDialog.kt @@ -18,6 +18,7 @@ import android.widget.CompoundButton import androidx.fragment.app.FragmentManager import dagger.android.HasAndroidInjector import dagger.android.support.DaggerDialogFragment +import info.nightscout.core.constraints.ConstraintObject import info.nightscout.core.extensions.valueToUnits import info.nightscout.core.iob.round import info.nightscout.core.profile.ProfileSealed @@ -30,8 +31,7 @@ import info.nightscout.database.ValueWrapper import info.nightscout.database.impl.AppRepository import info.nightscout.interfaces.Constants import info.nightscout.interfaces.GlucoseUnit -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.plugin.ActivePlugin import info.nightscout.interfaces.profile.Profile @@ -65,7 +65,7 @@ class WizardDialog : DaggerDialogFragment() { @Inject lateinit var injector: HasAndroidInjector @Inject lateinit var aapsLogger: AAPSLogger @Inject lateinit var aapsSchedulers: AapsSchedulers - @Inject lateinit var constraintChecker: Constraints + @Inject lateinit var constraintChecker: ConstraintsChecker @Inject lateinit var ctx: Context @Inject lateinit var sp: SP @Inject lateinit var rxBus: RxBus @@ -444,7 +444,7 @@ class WizardDialog : DaggerDialogFragment() { SafeParse.stringToDouble(binding.correctionInput.text) } else sp.getInt(info.nightscout.core.utils.R.string.key_boluswizard_percentage, 100).toDouble() - val carbsAfterConstraint = constraintChecker.applyCarbsConstraints(Constraint(carbs)).value() + val carbsAfterConstraint = constraintChecker.applyCarbsConstraints(ConstraintObject(carbs, injector)).value() if (abs(carbs - carbsAfterConstraint) > 0.01) { binding.carbsInput.value = 0.0 ToastUtils.warnToast(ctx, R.string.carbs_constraint_applied) diff --git a/ui/src/main/java/info/nightscout/ui/widget/Widget.kt b/ui/src/main/java/info/nightscout/ui/widget/Widget.kt index beaadb4a0a..972fe0c565 100644 --- a/ui/src/main/java/info/nightscout/ui/widget/Widget.kt +++ b/ui/src/main/java/info/nightscout/ui/widget/Widget.kt @@ -22,7 +22,7 @@ import info.nightscout.interfaces.Config import info.nightscout.interfaces.GlucoseUnit import info.nightscout.interfaces.aps.Loop import info.nightscout.interfaces.aps.VariableSensitivityResult -import info.nightscout.interfaces.constraints.Constraints +import info.nightscout.interfaces.constraints.ConstraintsChecker import info.nightscout.interfaces.iob.GlucoseStatusProvider import info.nightscout.interfaces.iob.IobCobCalculator import info.nightscout.interfaces.plugin.ActivePlugin @@ -62,10 +62,11 @@ class Widget : AppWidgetProvider() { @Inject lateinit var loop: Loop @Inject lateinit var config: Config @Inject lateinit var sp: SP - @Inject lateinit var constraintChecker: Constraints + @Inject lateinit var constraintChecker: ConstraintsChecker @Inject lateinit var decimalFormatter: DecimalFormatter companion object { + // This object doesn't behave like singleton, // many threads were created. Making handler static resolve this issue private var handler = Handler(HandlerThread(this::class.simpleName + "Handler").also { it.start() }.looper) @@ -78,6 +79,7 @@ class Widget : AppWidgetProvider() { }) } } + private val intentAction = "OpenApp" override fun onReceive(context: Context, intent: Intent?) { @@ -133,9 +135,9 @@ class Widget : AppWidgetProvider() { overviewData.lastBg(iobCobCalculator.ads)?.let { profileUtil.fromMgdlToStringInUnits(it.value) } ?: rh.gs(info.nightscout.core.ui.R.string.value_unavailable_short)) views.setTextColor( R.id.bg, when { - overviewData.isLow(iobCobCalculator.ads) -> rh.gc(info.nightscout.core.ui.R.color.widget_low) + overviewData.isLow(iobCobCalculator.ads) -> rh.gc(info.nightscout.core.ui.R.color.widget_low) overviewData.isHigh(iobCobCalculator.ads) -> rh.gc(info.nightscout.core.ui.R.color.widget_high) - else -> rh.gc(info.nightscout.core.ui.R.color.widget_inrange) + else -> rh.gc(info.nightscout.core.ui.R.color.widget_inrange) } ) trendCalculator.getTrendArrow(iobCobCalculator.ads)?.let {