refactor ConstraintObject
This commit is contained in:
parent
49c44a52b9
commit
d939f7ba99
127 changed files with 1818 additions and 1367 deletions
|
@ -2,6 +2,8 @@ package info.nightscout.sharedtests
|
|||
|
||||
import android.annotation.SuppressLint
|
||||
import 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")
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
|
@ -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<View>, position: Int): Matcher<View> {
|
||||
|
||||
return object : TypeSafeMatcher<View>() {
|
||||
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<View>, position: Int): Matcher<View> {
|
||||
|
||||
return object : TypeSafeMatcher<View>() {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
package info.nightscout.androidaps.di
|
||||
|
|
@ -8,8 +8,7 @@ import info.nightscout.core.utils.fabric.FabricPrivacy
|
|||
import info.nightscout.database.impl.AppRepository
|
||||
import info.nightscout.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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Int> = 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<Double> = 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")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,115 +1,18 @@
|
|||
package info.nightscout.interfaces.constraints
|
||||
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.logging.LTag
|
||||
|
||||
class Constraint<T : Comparable<T>>(private var value: T) {
|
||||
|
||||
private var originalValue: T
|
||||
private val reasons: MutableList<String> = ArrayList()
|
||||
private val mostLimiting: MutableList<String> = ArrayList()
|
||||
fun value(): T {
|
||||
return value
|
||||
}
|
||||
|
||||
fun originalValue(): T {
|
||||
return originalValue
|
||||
}
|
||||
|
||||
fun set(aapsLogger: AAPSLogger, value: T): Constraint<T> {
|
||||
this.value = value
|
||||
originalValue = value
|
||||
aapsLogger.debug(LTag.CONSTRAINTS, "Setting value $value")
|
||||
return this
|
||||
}
|
||||
|
||||
fun set(aapsLogger: AAPSLogger, value: T, reason: String, from: Any): Constraint<T> {
|
||||
aapsLogger.debug(LTag.CONSTRAINTS, "Setting value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]")
|
||||
this.value = value
|
||||
addReason(reason, from)
|
||||
addMostLimingReason(reason, from)
|
||||
return this
|
||||
}
|
||||
|
||||
fun setIfDifferent(aapsLogger: AAPSLogger, value: T, reason: String, from: Any): Constraint<T> {
|
||||
if (this.value != value) {
|
||||
aapsLogger.debug(LTag.CONSTRAINTS, "Setting because of different value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]")
|
||||
this.value = value
|
||||
addReason(reason, from)
|
||||
addMostLimingReason(reason, from)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
fun setIfSmaller(aapsLogger: AAPSLogger, value: T, reason: String, from: Any): Constraint<T> {
|
||||
if (value < this.value) {
|
||||
aapsLogger.debug(LTag.CONSTRAINTS, "Setting because of smaller value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]")
|
||||
this.value = value
|
||||
mostLimiting.clear()
|
||||
addMostLimingReason(reason, from)
|
||||
}
|
||||
if (value < originalValue) {
|
||||
addReason(reason, from)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
fun setIfGreater(aapsLogger: AAPSLogger, value: T, reason: String, from: Any): Constraint<T> {
|
||||
if (value > this.value) {
|
||||
aapsLogger.debug(LTag.CONSTRAINTS, "Setting because of greater value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]")
|
||||
this.value = value
|
||||
mostLimiting.clear()
|
||||
addMostLimingReason(reason, from)
|
||||
}
|
||||
if (value > originalValue) {
|
||||
addReason(reason, from)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
private fun translateFrom(from: Any): String {
|
||||
return from.javaClass.simpleName.replace("Plugin", "")
|
||||
}
|
||||
|
||||
fun addReason(reason: String, from: Any) {
|
||||
reasons.add(translateFrom(from) + ": " + reason)
|
||||
}
|
||||
|
||||
private fun addMostLimingReason(reason: String, from: Any) {
|
||||
mostLimiting.add(translateFrom(from) + ": " + reason)
|
||||
}
|
||||
|
||||
fun getReasons(aapsLogger: AAPSLogger): String {
|
||||
val sb = StringBuilder()
|
||||
for ((count, r) in reasons.withIndex()) {
|
||||
if (count != 0) sb.append("\n")
|
||||
sb.append(r)
|
||||
}
|
||||
aapsLogger.debug(LTag.CONSTRAINTS, "Limiting original value: $originalValue to $value. Reason: $sb")
|
||||
return sb.toString()
|
||||
}
|
||||
interface Constraint<T : Comparable<T>> {
|
||||
|
||||
fun value(): T
|
||||
fun originalValue(): T
|
||||
fun set(value: T): Constraint<T>
|
||||
fun set(value: T, reason: String, from: Any): Constraint<T>
|
||||
fun setIfDifferent(value: T, reason: String, from: Any): Constraint<T>
|
||||
fun setIfSmaller(value: T, reason: String, from: Any): Constraint<T>
|
||||
fun setIfGreater(value: T, reason: String, from: Any): Constraint<T>
|
||||
fun addReason(reason: String, from: Any)
|
||||
fun getReasons(): String
|
||||
val reasonList: List<String>
|
||||
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<String>
|
||||
get() = mostLimiting
|
||||
|
||||
fun copyReasons(another: Constraint<*>) {
|
||||
reasons.addAll(another.reasonList)
|
||||
}
|
||||
|
||||
init {
|
||||
originalValue = value
|
||||
}
|
||||
fun copyReasons(another: Constraint<*>)
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
package info.nightscout.interfaces.constraints
|
||||
|
||||
import info.nightscout.interfaces.Constants
|
||||
import info.nightscout.interfaces.profile.Profile
|
||||
|
||||
/**
|
||||
* Constraints interface
|
||||
*
|
||||
* Every function has a param from previous chained call
|
||||
* Function can limit the value even more and add another reason of restriction
|
||||
*
|
||||
* see [info.nightscout.plugins.constraints.ConstraintsImpl]
|
||||
* which iterates over all registered plugins with [Constraints] implemented
|
||||
*
|
||||
* @return updated parameter
|
||||
*/
|
||||
interface Constraints {
|
||||
|
||||
fun isLoopInvocationAllowed(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
||||
fun isClosedLoopAllowed(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
||||
fun isLgsAllowed(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
||||
fun isAutosensModeEnabled(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
||||
fun isSMBModeEnabled(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
||||
fun isDynIsfModeEnabled(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
||||
fun isUAMEnabled(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
||||
fun isAdvancedFilteringEnabled(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
||||
fun isSuperBolusEnabled(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
||||
fun isAutomationEnabled(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
||||
fun applyBasalConstraints(absoluteRate: Constraint<Double>, profile: Profile): Constraint<Double> = absoluteRate
|
||||
fun applyBasalPercentConstraints(percentRate: Constraint<Int>, profile: Profile): Constraint<Int> = percentRate
|
||||
fun applyBolusConstraints(insulin: Constraint<Double>): Constraint<Double> = insulin
|
||||
fun applyExtendedBolusConstraints(insulin: Constraint<Double>): Constraint<Double> = insulin
|
||||
fun applyCarbsConstraints(carbs: Constraint<Int>): Constraint<Int> = carbs
|
||||
fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> = maxIob
|
||||
|
||||
/*
|
||||
* Determine max values by walking through all constraints
|
||||
*/
|
||||
fun getMaxBasalAllowed(profile: Profile): Constraint<Double> =
|
||||
applyBasalConstraints(Constraint(Constants.REALLYHIGHBASALRATE), profile)
|
||||
|
||||
fun getMaxBasalPercentAllowed(profile: Profile): Constraint<Int> =
|
||||
applyBasalPercentConstraints(Constraint(Constants.REALLYHIGHPERCENTBASALRATE), profile)
|
||||
|
||||
fun getMaxBolusAllowed(): Constraint<Double> =
|
||||
applyBolusConstraints(Constraint(Constants.REALLYHIGHBOLUS))
|
||||
|
||||
fun getMaxExtendedBolusAllowed(): Constraint<Double> =
|
||||
applyExtendedBolusConstraints(Constraint(Constants.REALLYHIGHBOLUS))
|
||||
|
||||
fun getMaxCarbsAllowed(): Constraint<Int> =
|
||||
applyCarbsConstraints(Constraint(Constants.REALLYHIGHCARBS))
|
||||
|
||||
fun getMaxIOBAllowed(): Constraint<Double> =
|
||||
applyMaxIOBConstraints(Constraint(Constants.REALLYHIGHIOB))
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package info.nightscout.interfaces.constraints
|
||||
|
||||
import info.nightscout.interfaces.profile.Profile
|
||||
|
||||
/**
|
||||
* Constraints interface
|
||||
*
|
||||
* Every function has a param from previous chained call
|
||||
* Function can limit the value even more and add another reason of restriction
|
||||
*
|
||||
* see [info.nightscout.plugins.constraints.ConstraintsCheckerImpl]
|
||||
* which iterates over all registered plugins with [ConstraintsChecker] implemented
|
||||
*/
|
||||
interface ConstraintsChecker : PluginConstraints {
|
||||
|
||||
fun isLoopInvocationAllowed(): Constraint<Boolean>
|
||||
fun isClosedLoopAllowed(): Constraint<Boolean>
|
||||
fun isLgsAllowed(): Constraint<Boolean>
|
||||
fun isAutosensModeEnabled(): Constraint<Boolean>
|
||||
fun isSMBModeEnabled(): Constraint<Boolean>
|
||||
fun isDynIsfModeEnabled(): Constraint<Boolean>
|
||||
fun isUAMEnabled(): Constraint<Boolean>
|
||||
fun isAdvancedFilteringEnabled(): Constraint<Boolean>
|
||||
fun isSuperBolusEnabled(): Constraint<Boolean>
|
||||
fun isAutomationEnabled(): Constraint<Boolean>
|
||||
|
||||
/*
|
||||
* Determine max values by walking through all constraints
|
||||
*/
|
||||
fun getMaxBasalAllowed(profile: Profile): Constraint<Double>
|
||||
fun getMaxBasalPercentAllowed(profile: Profile): Constraint<Int>
|
||||
fun getMaxBolusAllowed(): Constraint<Double>
|
||||
fun getMaxExtendedBolusAllowed(): Constraint<Double>
|
||||
fun getMaxCarbsAllowed(): Constraint<Int>
|
||||
fun getMaxIOBAllowed(): Constraint<Double>
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package info.nightscout.interfaces.constraints
|
||||
|
||||
import info.nightscout.interfaces.profile.Profile
|
||||
|
||||
/**
|
||||
* PluginConstraints interface
|
||||
*
|
||||
* Allows to every plugin implement own constraints
|
||||
*/
|
||||
interface PluginConstraints {
|
||||
|
||||
fun isLoopInvocationAllowed(value: Constraint<Boolean>): Constraint<Boolean> = value
|
||||
fun isClosedLoopAllowed(value: Constraint<Boolean>): Constraint<Boolean> = value
|
||||
fun isLgsAllowed(value: Constraint<Boolean>): Constraint<Boolean> = value
|
||||
fun isAutosensModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> = value
|
||||
fun isSMBModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> = value
|
||||
fun isDynIsfModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> = value
|
||||
fun isUAMEnabled(value: Constraint<Boolean>): Constraint<Boolean> = value
|
||||
fun isAdvancedFilteringEnabled(value: Constraint<Boolean>): Constraint<Boolean> = value
|
||||
fun isSuperBolusEnabled(value: Constraint<Boolean>): Constraint<Boolean> = value
|
||||
fun isAutomationEnabled(value: Constraint<Boolean>): Constraint<Boolean> = value
|
||||
fun applyBasalConstraints(absoluteRate: Constraint<Double>, profile: Profile): Constraint<Double> = absoluteRate
|
||||
fun applyBasalPercentConstraints(percentRate: Constraint<Int>, profile: Profile): Constraint<Int> = percentRate
|
||||
fun applyBolusConstraints(insulin: Constraint<Double>): Constraint<Double> = insulin
|
||||
fun applyExtendedBolusConstraints(insulin: Constraint<Double>): Constraint<Double> = insulin
|
||||
fun applyCarbsConstraints(carbs: Constraint<Int>): Constraint<Int> = carbs
|
||||
fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> = maxIob
|
||||
}
|
|
@ -20,6 +20,7 @@ dependencies {
|
|||
implementation project(':core:utils')
|
||||
|
||||
testImplementation project(':app-wear-shared:shared-tests')
|
||||
testImplementation project(':app-wear-shared:shared-impl')
|
||||
|
||||
api "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
package info.nightscout.core.constraints
|
||||
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.interfaces.constraints.Constraint
|
||||
import info.nightscout.rx.logging.AAPSLogger
|
||||
import info.nightscout.rx.logging.LTag
|
||||
import javax.inject.Inject
|
||||
|
||||
class ConstraintObject<T : Comparable<T>>(private var value: T, injector: HasAndroidInjector) : Constraint<T> {
|
||||
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
|
||||
private var originalValue: T
|
||||
private val reasons: MutableList<String> = ArrayList()
|
||||
private val mostLimiting: MutableList<String> = ArrayList()
|
||||
override fun value(): T {
|
||||
return value
|
||||
}
|
||||
|
||||
override fun originalValue(): T {
|
||||
return originalValue
|
||||
}
|
||||
|
||||
override fun set(value: T): Constraint<T> {
|
||||
this.value = value
|
||||
originalValue = value
|
||||
aapsLogger.debug(LTag.CONSTRAINTS, "Setting value $value")
|
||||
return this
|
||||
}
|
||||
|
||||
override fun set(value: T, reason: String, from: Any): Constraint<T> {
|
||||
aapsLogger.debug(LTag.CONSTRAINTS, "Setting value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]")
|
||||
this.value = value
|
||||
addReason(reason, from)
|
||||
addMostLimingReason(reason, from)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun setIfDifferent(value: T, reason: String, from: Any): Constraint<T> {
|
||||
if (this.value != value) {
|
||||
aapsLogger.debug(LTag.CONSTRAINTS, "Setting because of different value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]")
|
||||
this.value = value
|
||||
addReason(reason, from)
|
||||
addMostLimingReason(reason, from)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
override fun setIfSmaller(value: T, reason: String, from: Any): Constraint<T> {
|
||||
if (value < this.value) {
|
||||
aapsLogger.debug(LTag.CONSTRAINTS, "Setting because of smaller value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]")
|
||||
this.value = value
|
||||
mostLimiting.clear()
|
||||
addMostLimingReason(reason, from)
|
||||
}
|
||||
if (value < originalValue) {
|
||||
addReason(reason, from)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
override fun setIfGreater(value: T, reason: String, from: Any): Constraint<T> {
|
||||
if (value > this.value) {
|
||||
aapsLogger.debug(LTag.CONSTRAINTS, "Setting because of greater value " + this.value + " -> " + value + " (" + reason + ")[" + translateFrom(from) + "]")
|
||||
this.value = value
|
||||
mostLimiting.clear()
|
||||
addMostLimingReason(reason, from)
|
||||
}
|
||||
if (value > originalValue) {
|
||||
addReason(reason, from)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
private fun translateFrom(from: Any): String {
|
||||
return from.javaClass.simpleName.replace("Plugin", "")
|
||||
}
|
||||
|
||||
override fun addReason(reason: String, from: Any) {
|
||||
reasons.add(translateFrom(from) + ": " + reason)
|
||||
}
|
||||
|
||||
private fun addMostLimingReason(reason: String, from: Any) {
|
||||
mostLimiting.add(translateFrom(from) + ": " + reason)
|
||||
}
|
||||
|
||||
override fun getReasons(): String {
|
||||
val sb = StringBuilder()
|
||||
for ((count, r) in reasons.withIndex()) {
|
||||
if (count != 0) sb.append("\n")
|
||||
sb.append(r)
|
||||
}
|
||||
aapsLogger.debug(LTag.CONSTRAINTS, "Limiting original value: $originalValue to $value. Reason: $sb")
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
override val reasonList: List<String>
|
||||
get() = reasons
|
||||
|
||||
override fun getMostLimitedReasons(): String {
|
||||
val sb = StringBuilder()
|
||||
for ((count, r) in mostLimiting.withIndex()) {
|
||||
if (count != 0) sb.append("\n")
|
||||
sb.append(r)
|
||||
}
|
||||
aapsLogger.debug(LTag.CONSTRAINTS, "Limiting original value: $originalValue to $value. Reason: $sb")
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
override val mostLimitedReasonList: List<String>
|
||||
get() = mostLimiting
|
||||
|
||||
override fun copyReasons(another: Constraint<*>) {
|
||||
reasons.addAll(another.reasonList)
|
||||
}
|
||||
|
||||
init {
|
||||
injector.androidInjector().inject(this)
|
||||
originalValue = value
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import android.content.Context
|
|||
import android.text.Spanned
|
||||
import 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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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'
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<ActiveBolus> 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<Integer> applyBasalPercentConstraints(Constraint<Integer> percentRate, @NonNull Profile profile) {
|
||||
percentRate.setIfGreater(getAapsLogger(), 0, rh.gs(info.nightscout.core.ui.R.string.limitingpercentrate, 0, rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), this);
|
||||
percentRate.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<Double> applyBolusConstraints(@NonNull Constraint<Double> 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;
|
||||
}
|
||||
|
|
|
@ -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) + "<br>" else if (rate == -1.0) rh.gs(info.nightscout.core.ui.R.string.let_temp_basal_run) + "<br>" else if (usePercent) "<b>" + rh.gs(
|
||||
info.nightscout.core.ui.R.string.rate
|
||||
if (rate == 0.0 && duration == 0) rh.gs(R.string.cancel_temp) + "<br>" else if (rate == -1.0) rh.gs(R.string.let_temp_basal_run) + "<br>" else if (usePercent) "<b>" + rh.gs(
|
||||
R.string.rate
|
||||
) + "</b>: " + decimalFormatter.to2Decimal(
|
||||
percent.toDouble()
|
||||
) + "% " +
|
||||
"(" + decimalFormatter.to2Decimal(percent * pump.baseBasalRate / 100.0) + " U/h)<br>" +
|
||||
"<b>" + rh.gs(info.nightscout.core.ui.R.string.duration) + "</b>: " + decimalFormatter.to2Decimal(duration.toDouble()) + " min<br>" else "<b>" + rh.gs(info.nightscout.core.ui.R.string.rate) + "</b>: " + decimalFormatter.to2Decimal(
|
||||
"<b>" + rh.gs(R.string.duration) + "</b>: " + decimalFormatter.to2Decimal(duration.toDouble()) + " min<br>" else "<b>" + rh.gs(R.string.rate) + "</b>: " + decimalFormatter.to2Decimal(
|
||||
rate
|
||||
) + " U/h " +
|
||||
"(" + decimalFormatter.to2Decimal(rate / pump.baseBasalRate * 100.0) + "%) <br>" +
|
||||
"<b>" + rh.gs(info.nightscout.core.ui.R.string.duration) + "</b>: " + decimalFormatter.to2Decimal(duration.toDouble()) + " min<br>"
|
||||
"<b>" + rh.gs(R.string.duration) + "</b>: " + decimalFormatter.to2Decimal(duration.toDouble()) + " min<br>"
|
||||
|
||||
// smb
|
||||
if (smb != 0.0) ret += "<b>" + "SMB" + "</b>: " + decimalFormatter.toPumpSupportedBolus(smb, activePlugin.activePump.pumpDescription.bolusStep) + "<br>"
|
||||
|
|
|
@ -150,7 +150,7 @@ class OpenAPSFragment : DaggerFragment(), MenuProvider {
|
|||
binding.mealdata.text = jsonFormatter.format(determineBasalAdapter.mealDataParam)
|
||||
binding.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) {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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<Double>): Constraint<Double> {
|
||||
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<Boolean>): Constraint<Boolean> {
|
||||
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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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<Boolean> = Constraint(false)
|
||||
var dynIsfEnabled: Constraint<Boolean> = 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<Boolean>): Constraint<Boolean> {
|
||||
value.set(aapsLogger, false)
|
||||
value.set(false)
|
||||
return value
|
||||
}
|
||||
|
||||
override fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> {
|
||||
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<Boolean>): Constraint<Boolean> {
|
||||
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<Boolean>): Constraint<Boolean> {
|
||||
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<Boolean>): Constraint<Boolean> {
|
||||
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
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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')
|
||||
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Boolean>? = Constraint(true)
|
||||
override var closedLoopEnabled: Constraint<Boolean>? = 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<Boolean> = isLoopInvocationAllowed(ConstraintObject(true, injector))
|
||||
|
||||
override fun isLoopInvocationAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)
|
||||
for (p in constraintsPlugins) {
|
||||
val constraint = p as Constraints
|
||||
val constraint = p as PluginConstraints
|
||||
if (!p.isEnabled()) continue
|
||||
constraint.isLoopInvocationAllowed(value)
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
override fun isClosedLoopAllowed(): Constraint<Boolean> = isClosedLoopAllowed(ConstraintObject(true, injector))
|
||||
|
||||
override fun isClosedLoopAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)
|
||||
for (p in constraintsPlugins) {
|
||||
val constraint = p as Constraints
|
||||
val constraint = p as PluginConstraints
|
||||
if (!p.isEnabled()) continue
|
||||
constraint.isClosedLoopAllowed(value)
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
override fun isLgsAllowed(): Constraint<Boolean> = isLgsAllowed(ConstraintObject(true, injector))
|
||||
|
||||
override fun isLgsAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)
|
||||
for (p in constraintsPlugins) {
|
||||
val constraint = p as Constraints
|
||||
val constraint = p as PluginConstraints
|
||||
if (!p.isEnabled()) continue
|
||||
constraint.isLgsAllowed(value)
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
override fun isAutosensModeEnabled(): Constraint<Boolean> = isAutosensModeEnabled(ConstraintObject(true, injector))
|
||||
|
||||
override fun isAutosensModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)
|
||||
for (p in constraintsPlugins) {
|
||||
val constraint = p as Constraints
|
||||
val constraint = p as PluginConstraints
|
||||
if (!p.isEnabled()) continue
|
||||
constraint.isAutosensModeEnabled(value)
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
override fun isSMBModeEnabled(): Constraint<Boolean> = isSMBModeEnabled(ConstraintObject(true, injector))
|
||||
|
||||
override fun isSMBModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)
|
||||
for (p in constraintsPlugins) {
|
||||
val constraint = p as Constraints
|
||||
val constraint = p as PluginConstraints
|
||||
if (!p.isEnabled()) continue
|
||||
constraint.isSMBModeEnabled(value)
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
override fun isDynIsfModeEnabled(): Constraint<Boolean> = isDynIsfModeEnabled(ConstraintObject(true, injector))
|
||||
|
||||
override fun isDynIsfModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)
|
||||
for (p in constraintsPlugins) {
|
||||
val constraint = p as Constraints
|
||||
val constraint = p as PluginConstraints
|
||||
if (!p.isEnabled()) continue
|
||||
constraint.isDynIsfModeEnabled(value)
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
override fun isUAMEnabled(): Constraint<Boolean> = isUAMEnabled(ConstraintObject(true, injector))
|
||||
|
||||
override fun isUAMEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)
|
||||
for (p in constraintsPlugins) {
|
||||
val constraint = p as Constraints
|
||||
val constraint = p as PluginConstraints
|
||||
if (!p.isEnabled()) continue
|
||||
constraint.isUAMEnabled(value)
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
override fun isAdvancedFilteringEnabled(): Constraint<Boolean> = isAdvancedFilteringEnabled(ConstraintObject(true, injector))
|
||||
|
||||
override fun isAdvancedFilteringEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)
|
||||
for (p in constraintsPlugins) {
|
||||
val constraint = p as Constraints
|
||||
val constraint = p as PluginConstraints
|
||||
if (!p.isEnabled()) continue
|
||||
constraint.isAdvancedFilteringEnabled(value)
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
override fun isSuperBolusEnabled(): Constraint<Boolean> = isSuperBolusEnabled(ConstraintObject(true, injector))
|
||||
|
||||
override fun isSuperBolusEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)
|
||||
for (p in constraintsPlugins) {
|
||||
val constraint = p as Constraints
|
||||
val constraint = p as PluginConstraints
|
||||
if (!p.isEnabled()) continue
|
||||
constraint.isSuperBolusEnabled(value)
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
override fun isAutomationEnabled(): Constraint<Boolean> = isAutomationEnabled(ConstraintObject(true, injector))
|
||||
|
||||
override fun applyBasalConstraints(absoluteRate: Constraint<Double>, profile: Profile): Constraint<Double> {
|
||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(PluginConstraints::class.java)
|
||||
for (p in constraintsPlugins) {
|
||||
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<Int>, profile: Profile): Constraint<Int> {
|
||||
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<Double>): Constraint<Double> {
|
||||
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<Double>): Constraint<Double> {
|
||||
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<Int>): Constraint<Int> {
|
||||
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<Double>): Constraint<Double> {
|
||||
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<Boolean>): Constraint<Boolean> {
|
||||
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<Double> =
|
||||
applyBasalConstraints(ConstraintObject(Double.MAX_VALUE, injector), profile)
|
||||
|
||||
override fun getMaxBasalPercentAllowed(profile: Profile): Constraint<Int> =
|
||||
applyBasalPercentConstraints(ConstraintObject(Int.MAX_VALUE, injector), profile)
|
||||
|
||||
override fun getMaxBolusAllowed(): Constraint<Double> =
|
||||
applyBolusConstraints(ConstraintObject(Double.MAX_VALUE, injector))
|
||||
|
||||
override fun getMaxExtendedBolusAllowed(): Constraint<Double> =
|
||||
applyExtendedBolusConstraints(ConstraintObject(Double.MAX_VALUE, injector))
|
||||
|
||||
override fun getMaxCarbsAllowed(): Constraint<Int> =
|
||||
applyCarbsConstraints(ConstraintObject(Int.MAX_VALUE, injector))
|
||||
|
||||
override fun getMaxIOBAllowed(): Constraint<Double> =
|
||||
applyMaxIOBConstraints(ConstraintObject(Double.MAX_VALUE, injector))
|
||||
}
|
|
@ -5,7 +5,7 @@ import dagger.android.HasAndroidInjector
|
|||
import info.nightscout.core.utils.fabric.FabricPrivacy
|
||||
import info.nightscout.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<Double>): Constraint<Double> =
|
||||
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
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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<Objective> = ArrayList()
|
||||
|
||||
|
@ -112,49 +112,49 @@ class ObjectivesPlugin @Inject constructor(
|
|||
*/
|
||||
override fun isLoopInvocationAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||
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<Boolean>): Constraint<Boolean> {
|
||||
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<Boolean>): Constraint<Boolean> {
|
||||
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<Boolean>): Constraint<Boolean> {
|
||||
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<Boolean>): Constraint<Boolean> {
|
||||
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<Boolean>): Constraint<Boolean> {
|
||||
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<Double>): Constraint<Double> {
|
||||
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<Boolean>): Constraint<Boolean> {
|
||||
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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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()))
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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<Boolean>): Constraint<Boolean> {
|
||||
if (!activePlugin.activePump.pumpDescription.isTempBasalCapable) value.set(aapsLogger, false, rh.gs(R.string.pumpisnottempbasalcapable), this)
|
||||
if (!activePlugin.activePump.pumpDescription.isTempBasalCapable) value.set(false, rh.gs(R.string.pumpisnottempbasalcapable), this)
|
||||
return value
|
||||
}
|
||||
|
||||
override fun isClosedLoopAllowed(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||
val mode = ApsMode.fromString(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name))
|
||||
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<Boolean>): Constraint<Boolean> {
|
||||
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<Boolean>): Constraint<Boolean> {
|
||||
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<Double>, profile: Profile): Constraint<Double> {
|
||||
absoluteRate.setIfGreater(aapsLogger, 0.0, rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, 0.0, rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), this)
|
||||
absoluteRate.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<Double>): Constraint<Double> {
|
||||
insulin.setIfGreater(aapsLogger, 0.0, rh.gs(info.nightscout.core.ui.R.string.limitingbolus, 0.0, rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), this)
|
||||
insulin.setIfGreater(0.0, rh.gs(info.nightscout.core.ui.R.string.limitingbolus, 0.0, rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), this)
|
||||
val maxBolus = sp.getDouble(info.nightscout.core.utils.R.string.key_treatmentssafety_maxbolus, 3.0)
|
||||
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<Double>): Constraint<Double> {
|
||||
insulin.setIfGreater(aapsLogger, 0.0, rh.gs(R.string.limitingextendedbolus, 0.0, rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), this)
|
||||
insulin.setIfGreater(0.0, rh.gs(R.string.limitingextendedbolus, 0.0, rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), this)
|
||||
val maxBolus = sp.getDouble(info.nightscout.core.utils.R.string.key_treatmentssafety_maxbolus, 3.0)
|
||||
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<Int>): Constraint<Int> {
|
||||
carbs.setIfGreater(aapsLogger, 0, rh.gs(R.string.limitingcarbs, 0, rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), this)
|
||||
carbs.setIfGreater(0, rh.gs(R.string.limitingcarbs, 0, rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), this)
|
||||
val maxCarbs = sp.getInt(info.nightscout.core.utils.R.string.key_treatmentssafety_maxcarbs, 48)
|
||||
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<Double>): Constraint<Double> {
|
||||
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
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Boolean>): Constraint<Boolean> {
|
||||
if (hasIllegalSignature()) {
|
||||
showNotification()
|
||||
value.set(aapsLogger, false)
|
||||
value.set(false)
|
||||
}
|
||||
if (shouldDownloadCerts()) {
|
||||
handler.post {
|
||||
|
|
|
@ -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<Boolean>): Constraint<Boolean> {
|
||||
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
|
||||
|
|
|
@ -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<Double>): Constraint<Double> =
|
||||
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
|
||||
|
||||
|
|
|
@ -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<GlucoseValue> = ArrayList()
|
||||
superData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
superData.add(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<GlucoseValue> = ArrayList()
|
||||
flatData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = now + T.mins(0).msecs(), sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
flatData.add(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<GlucoseValue> = ArrayList()
|
||||
flatDataDexcom.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = now + T.mins(0).msecs(), sourceSensor = GlucoseValue.SourceSensor.DEXCOM_G6_NATIVE, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
flatDataDexcom.add(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<GlucoseValue> = ArrayList()
|
||||
incompleteData.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = now + T.mins(0).msecs(), sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_OTHER, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||
incompleteData.add(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)
|
||||
}
|
||||
|
||||
}
|
|
@ -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())
|
||||
}
|
||||
}
|
|
@ -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())
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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<String>, 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()
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<Boolean>): Constraint<Boolean> {
|
||||
if (!isEnabled()) value.set(aapsLogger, false, rh.gs(R.string.uam_disabled_oref1_not_selected), this)
|
||||
if (!isEnabled()) value.set(false, rh.gs(R.string.uam_disabled_oref1_not_selected), this)
|
||||
return value
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<Bolus> 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<Boolean> isLoopInvocationAllowed(@NonNull Constraint<Boolean> 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<Double> applyMaxIOBConstraints(@NonNull Constraint<Double> 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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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<ReservoirLevel?>(null)
|
||||
val reservoirLevelUIFlow = _reservoirLevelUIFlow.asStateFlow()
|
||||
|
||||
|
@ -1830,7 +1853,6 @@ class ComboV2Plugin @Inject constructor (
|
|||
private var _displayFrameUIFlow = MutableSharedFlow<DisplayFrame?>(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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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<Double> applyBasalConstraints(Constraint<Double> absoluteRate, @NonNull Profile profile) {
|
||||
absoluteRate.setIfSmaller(getAapsLogger(), danaPump.getMaxBasal(), getRh().gs(info.nightscout.core.ui.R.string.limitingbasalratio, danaPump.getMaxBasal(), getRh().gs(info.nightscout.core.ui.R.string.pumplimit)), this);
|
||||
absoluteRate.setIfSmaller(danaPump.getMaxBasal(), getRh().gs(info.nightscout.core.ui.R.string.limitingbasalratio, danaPump.getMaxBasal(), getRh().gs(info.nightscout.core.ui.R.string.pumplimit)), this);
|
||||
return absoluteRate;
|
||||
}
|
||||
|
||||
@NonNull @Override
|
||||
public Constraint<Integer> applyBasalPercentConstraints(Constraint<Integer> percentRate, @NonNull Profile profile) {
|
||||
percentRate.setIfGreater(getAapsLogger(), 0, getRh().gs(info.nightscout.core.ui.R.string.limitingpercentrate, 0, getRh().gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), this);
|
||||
percentRate.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<Double> applyBolusConstraints(Constraint<Double> insulin) {
|
||||
insulin.setIfSmaller(getAapsLogger(), danaPump.getMaxBolus(), getRh().gs(info.nightscout.core.ui.R.string.limitingbolus, danaPump.getMaxBolus(), getRh().gs(info.nightscout.core.ui.R.string.pumplimit)), this);
|
||||
insulin.setIfSmaller(danaPump.getMaxBolus(), getRh().gs(info.nightscout.core.ui.R.string.limitingbolus, danaPump.getMaxBolus(), getRh().gs(info.nightscout.core.ui.R.string.pumplimit)), this);
|
||||
return insulin;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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<Double>, profile: Profile): Constraint<Double> {
|
||||
absoluteRate.setIfSmaller(aapsLogger, danaPump.maxBasal, rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, danaPump.maxBasal, rh.gs(info.nightscout.core.ui.R.string.pumplimit)), this)
|
||||
absoluteRate.setIfSmaller(danaPump.maxBasal, rh.gs(info.nightscout.core.ui.R.string.limitingbasalratio, danaPump.maxBasal, rh.gs(info.nightscout.core.ui.R.string.pumplimit)), this)
|
||||
return absoluteRate
|
||||
}
|
||||
|
||||
override fun applyBasalPercentConstraints(percentRate: Constraint<Int>, profile: Profile): Constraint<Int> {
|
||||
percentRate.setIfGreater(aapsLogger, 0, rh.gs(info.nightscout.core.ui.R.string.limitingpercentrate, 0, rh.gs(info.nightscout.core.ui.R.string.itmustbepositivevalue)), this)
|
||||
percentRate.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<Double>): Constraint<Double> {
|
||||
insulin.setIfSmaller(aapsLogger, danaPump.maxBolus, rh.gs(info.nightscout.core.ui.R.string.limitingbolus, danaPump.maxBolus, rh.gs(info.nightscout.core.ui.R.string.pumplimit)), this)
|
||||
insulin.setIfSmaller(danaPump.maxBolus, rh.gs(info.nightscout.core.ui.R.string.limitingbolus, danaPump.maxBolus, rh.gs(info.nightscout.core.ui.R.string.pumplimit)), this)
|
||||
return insulin
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue